From 34b242684be7aafbcdc746e0d814b5d49b8553da Mon Sep 17 00:00:00 2001 From: "saito.k" Date: Wed, 14 Jun 2023 03:57:30 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20PR=20154:=20API=E5=AE=9F=E8=A3=85?= =?UTF-8?q?=EF=BC=88=E3=82=BF=E3=82=B9=E3=82=AF=E4=B8=80=E8=A6=A7=E5=8F=96?= =?UTF-8?q?=E5=BE=97=20|=20author=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task1949: API実装(タスク一覧取得 | author)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/1949) - タスク一覧取得(Author用) - AuthorIDとAccountIDを条件にタスクを取得する処理を実装 - テスト実装 - 成功ケースの時に、Repositoryのメソッドが正しい引数で呼ばれているか確認するテストを追加 ## レビューポイント - テスト実装の内容はこれでよいか - DBから取得した値をレスポンス用の型に変換する処理はAdminと同様の認識だがあっているか ## UIの変更 - Before/Afterのスクショなど - スクショ置き場 ## 動作確認状況 - ローカルで確認 - 実際にデータを取得して内容が正しいか確認 ## 補足 - 相談、参考資料などがあれば --- .../accounts/accounts.service.spec.ts | 2 +- .../src/features/tasks/tasks.service.spec.ts | 342 ++++++++++++------ .../src/features/tasks/tasks.service.ts | 19 +- .../features/tasks/test/tasks.service.mock.ts | 297 ++++++++------- .../tasks/tasks.repository.service.ts | 66 ++++ 5 files changed, 476 insertions(+), 250 deletions(-) diff --git a/dictation_server/src/features/accounts/accounts.service.spec.ts b/dictation_server/src/features/accounts/accounts.service.spec.ts index 95b696f..5209ec1 100644 --- a/dictation_server/src/features/accounts/accounts.service.spec.ts +++ b/dictation_server/src/features/accounts/accounts.service.spec.ts @@ -63,7 +63,7 @@ it('アクセストークンからユーザ情報を取得する', async () => { adb2cParam, sendGridMockValue, ); - expect(await service.getMyAccountInfo(token)).toEqual(userInfo); + expect(await service.getMyAccountInfo(token)).toEqual(1234567890123456); }); it('ユーザ情報が取得できない場合エラーとなる', async () => { const token = { diff --git a/dictation_server/src/features/tasks/tasks.service.spec.ts b/dictation_server/src/features/tasks/tasks.service.spec.ts index 23a9adc..45fa463 100644 --- a/dictation_server/src/features/tasks/tasks.service.spec.ts +++ b/dictation_server/src/features/tasks/tasks.service.spec.ts @@ -1,29 +1,28 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { TasksService } from './tasks.service'; -import { TasksRepositoryModule } from '../../repositories/tasks/tasks.repository.module'; -import { UsersRepositoryModule } from '../../repositories/users/users.repository.module'; -import { makeDefaultTasksRepositoryMockValue, makeDefaultUsersRepositoryMockValue, makeTasksServiceMock } from '../tasks/test/tasks.service.mock'; +import { + makeDefaultTasksRepositoryMockValue, + makeDefaultUsersRepositoryMockValue, + makeTasksServiceMock, +} from '../tasks/test/tasks.service.mock'; import { HttpException, HttpStatus } from '@nestjs/common'; import { makeErrorResponse } from '../../common/error/makeErrorResponse'; describe('TasksService', () => { it('タスク一覧を取得できる(admin)', async () => { - const tasksRepositoryMockValue = - makeDefaultTasksRepositoryMockValue(); + const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue(); const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue(); - const service = await makeTasksServiceMock( + const service = await makeTasksServiceMock( tasksRepositoryMockValue, usersRepositoryMockValue, ); - - const accessToken = { userId: "userId", role: "admin", tier: 5 }; + + const accessToken = { userId: 'userId', role: 'admin', tier: 5 }; const offset = 0; const limit = 20; - const status = ["Uploaded,Backup"]; - const paramName = "JOB_NUMBER"; - const direction = "ASC"; + const status = ['Uploaded,Backup']; + const paramName = 'JOB_NUMBER'; + const direction = 'ASC'; expect( - await service.getTasksFromAccountId( + await service.tasksService.getTasksFromAccountId( accessToken, offset, limit, @@ -72,38 +71,38 @@ describe('TasksService', () => { }); }); - it('アカウント情報の取得に失敗した場合、エラーを返却する(admin)', async () => { - const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue(); - const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue(); - usersRepositoryMockValue.findUserByExternalId = new Error("DB failed"); - const service = await makeTasksServiceMock( - tasksRepositoryMockValue, - usersRepositoryMockValue, - ); + it('アカウント情報の取得に失敗した場合、エラーを返却する', async () => { + const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue(); + const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue(); + usersRepositoryMockValue.findUserByExternalId = new Error('DB failed'); + const service = await makeTasksServiceMock( + tasksRepositoryMockValue, + usersRepositoryMockValue, + ); + + const accessToken = { userId: 'userId', role: 'admin', tier: 5 }; + const offset = 0; + const limit = 20; + const status = ['Uploaded,Backup']; + const paramName = 'JOB_NUMBER'; + const direction = 'ASC'; + await expect( + service.tasksService.getTasksFromAccountId( + accessToken, + offset, + limit, + status, + paramName, + direction, + ), + ).rejects.toEqual( + new HttpException( + makeErrorResponse('E000101'), + HttpStatus.INTERNAL_SERVER_ERROR, + ), + ); + }); - const accessToken = { userId: 'userId', role: 'admin', tier: 5 }; - const offset = 0; - const limit = 20; - const status = ['Uploaded,Backup']; - const paramName = 'JOB_NUMBER'; - const direction = 'ASC'; - await expect( - service.getTasksFromAccountId( - accessToken, - offset, - limit, - status, - paramName, - direction, - ), - ).rejects.toEqual( - new HttpException( - makeErrorResponse('E000101'), - HttpStatus.INTERNAL_SERVER_ERROR, - ), - ); - }); - it('タスク一覧の取得に失敗した場合、エラーを返却する(admin)', async () => { const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue(); const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue(); @@ -120,7 +119,7 @@ describe('TasksService', () => { const paramName = 'JOB_NUMBER'; const direction = 'ASC'; await expect( - service.getTasksFromAccountId( + service.tasksService.getTasksFromAccountId( accessToken, offset, limit, @@ -135,59 +134,58 @@ describe('TasksService', () => { ), ); }); - - it('取得したタスク一覧が不正な形式の場合、エラーを返却する(admin)', async () => { - const tasksRepositoryMockValue = - makeDefaultTasksRepositoryMockValue(); - tasksRepositoryMockValue.getTasksFromAccountId={ - tasks: [ - { + + it('取得したタスク一覧が不正な形式の場合、エラーを返却する', async () => { + const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue(); + tasksRepositoryMockValue.getTasksFromAccountId = { + tasks: [ + { + id: 1, + job_number: '00000001', + account_id: 1, + is_job_number_enabled: true, + audio_file_id: 1, + status: 'Uploaded', + priority: '00', + created_at: new Date('2023-01-01T01:01:01.000'), + option_items: undefined, + file: { id: 1, - job_number: '00000001', account_id: 1, - is_job_number_enabled: true, - audio_file_id: 1, - status: 'Uploaded', + owner_user_id: 1, + url: 'test/test.zip', + file_name: 'test.zip', + author_id: 'AUTHOR', + work_type_id: 'WorkType', + started_at: new Date('2023-01-01T01:01:01.000'), + duration: '123000', + finished_at: new Date('2023-01-01T01:01:01.000'), + uploaded_at: new Date('2023-01-01T01:01:01.000'), + file_size: 123000, priority: '00', - created_at: new Date('2023-01-01T01:01:01.000'), - option_items: undefined, - file: { - id: 1, - account_id: 1, - owner_user_id: 1, - url: 'test/test.zip', - file_name: 'test.zip', - author_id: 'AUTHOR', - work_type_id: 'WorkType', - started_at: new Date('2023-01-01T01:01:01.000'), - duration: '123000', - finished_at: new Date('2023-01-01T01:01:01.000'), - uploaded_at: new Date('2023-01-01T01:01:01.000'), - file_size: 123000, - priority: '00', - audio_format: 'DS', - comment: 'comment', - is_encrypted: true, - }, + audio_format: 'DS', + comment: 'comment', + is_encrypted: true, }, - ], - permissions: [], - count: 1, - } + }, + ], + permissions: [], + count: 1, + }; const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue(); - const service = await makeTasksServiceMock( + const service = await makeTasksServiceMock( tasksRepositoryMockValue, usersRepositoryMockValue, ); - - const accessToken = { userId: "userId", role: "admin", tier: 5 }; + + const accessToken = { userId: 'userId', role: 'admin', tier: 5 }; const offset = 0; const limit = 20; - const status = ["Uploaded,Backup"]; - const paramName = "JOB_NUMBER"; - const direction = "ASC"; + const status = ['Uploaded,Backup']; + const paramName = 'JOB_NUMBER'; + const direction = 'ASC'; await expect( - service.getTasksFromAccountId( + service.tasksService.getTasksFromAccountId( accessToken, offset, limit, @@ -202,36 +200,142 @@ describe('TasksService', () => { ), ); }); - - // TODO: 後続タスクでadmin以外の処理を実装するが、ここではエラーを返す - it('admin以外のRoleの場合、エラーを返却する(admin)', async () => { - const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue(); - const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue(); - const service = await makeTasksServiceMock( - tasksRepositoryMockValue, - usersRepositoryMockValue, - ); - const accessToken = { userId: 'userId', role: 'author', tier: 5 }; - const offset = 0; - const limit = 20; - const status = ['Uploaded,Backup']; - const paramName = 'JOB_NUMBER'; - const direction = 'ASC'; - await expect( - service.getTasksFromAccountId( - accessToken, - offset, - limit, - status, - paramName, - direction, - ), - ).rejects.toEqual( - new HttpException( - makeErrorResponse('E000101'), - HttpStatus.INTERNAL_SERVER_ERROR, - ), - ); - }); + it('タスク一覧を取得できる(author)', async () => { + const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue(); + const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue(); + if (usersRepositoryMockValue.findUserByExternalId instanceof Error) { + return; + } + usersRepositoryMockValue.findUserByExternalId.role = 'author'; + + const service = await makeTasksServiceMock( + tasksRepositoryMockValue, + usersRepositoryMockValue, + ); + + const accessToken = { userId: 'userId', role: 'author', tier: 5 }; + const offset = 0; + const limit = 20; + const status = ['Uploaded,Backup']; + const paramName = 'JOB_NUMBER'; + const direction = 'ASC'; + const result = await service.tasksService.getTasksFromAccountId( + accessToken, + offset, + limit, + status, + paramName, + direction, + ); + expect(result).toEqual({ + tasks: [ + { + assignees: [{ typistName: 'USER_userId', typistUserId: 1 }], + audioCreatedDate: '2023-01-01T01:01:01.000Z', + audioDuration: '123000', + audioFileId: 1, + audioFinishedDate: '2023-01-01T01:01:01.000Z', + audioFormat: 'DS', + audioUploadedDate: '2023-01-01T01:01:01.000Z', + authorId: 'AUTHOR', + comment: 'comment', + fileName: 'test.zip', + fileSize: 123000, + isEncrypted: true, + jobNumber: '00000001', + optionItemList: [ + { optionItemLabel: 'label01', optionItemValue: 'value01' }, + { optionItemLabel: 'label02', optionItemValue: 'value02' }, + { optionItemLabel: 'label03', optionItemValue: 'value03' }, + { optionItemLabel: 'label04', optionItemValue: 'value04' }, + { optionItemLabel: 'label05', optionItemValue: 'value05' }, + { optionItemLabel: 'label06', optionItemValue: 'value06' }, + { optionItemLabel: 'label07', optionItemValue: 'value07' }, + { optionItemLabel: 'label08', optionItemValue: 'value08' }, + { optionItemLabel: 'label09', optionItemValue: 'value09' }, + { optionItemLabel: 'label10', optionItemValue: 'value10' }, + ], + priority: '00', + status: 'Uploaded', + transcriptionFinishedDate: '', + transcriptionStartedDate: '', + typist: undefined, + url: 'test/test.zip', + workType: 'WorkType', + }, + ], + total: 1, + }); + expect( + service.taskRepoService.getTasksFromAuthorIdAndAccountId, + ).toHaveBeenCalledWith('abcdef', 1, 0, 20, 'JOB_NUMBER', 'ASC', [ + 'Uploaded,Backup', + ]); + }); + + it('タスク一覧の取得に失敗した場合、エラーを返却する(author)', async () => { + const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue(); + const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue(); + tasksRepositoryMockValue.getTasksFromAuthorIdAndAccountId = new Error( + 'DB failed', + ); + const service = await makeTasksServiceMock( + tasksRepositoryMockValue, + usersRepositoryMockValue, + ); + + const accessToken = { userId: 'userId', role: 'author', tier: 5 }; + const offset = 0; + const limit = 20; + const status = ['Uploaded,Backup']; + const paramName = 'JOB_NUMBER'; + const direction = 'ASC'; + await expect( + service.tasksService.getTasksFromAccountId( + accessToken, + offset, + limit, + status, + paramName, + direction, + ), + ).rejects.toEqual( + new HttpException( + makeErrorResponse('E000101'), + HttpStatus.INTERNAL_SERVER_ERROR, + ), + ); + }); + + it('想定外のRoleの場合、エラーを返却する', async () => { + const tasksRepositoryMockValue = makeDefaultTasksRepositoryMockValue(); + const usersRepositoryMockValue = makeDefaultUsersRepositoryMockValue(); + const service = await makeTasksServiceMock( + tasksRepositoryMockValue, + usersRepositoryMockValue, + ); + + const accessToken = { userId: 'userId', role: 'XXX', tier: 5 }; + const offset = 0; + const limit = 20; + const status = ['Uploaded,Backup']; + const paramName = 'JOB_NUMBER'; + const direction = 'ASC'; + await expect( + service.tasksService.getTasksFromAccountId( + accessToken, + offset, + limit, + status, + paramName, + direction, + ), + ).rejects.toEqual( + new HttpException( + makeErrorResponse('E000101'), + HttpStatus.INTERNAL_SERVER_ERROR, + ), + ); + }); }); diff --git a/dictation_server/src/features/tasks/tasks.service.ts b/dictation_server/src/features/tasks/tasks.service.ts index 949e815..2aadc77 100644 --- a/dictation_server/src/features/tasks/tasks.service.ts +++ b/dictation_server/src/features/tasks/tasks.service.ts @@ -36,9 +36,8 @@ export class TasksService { const defaultDirection: SortDirection = 'ASC'; try { - const { account_id } = await this.usersRepository.findUserByExternalId( - userId, - ); + const { account_id, author_id } = + await this.usersRepository.findUserByExternalId(userId); if (roles.includes(ADMIN_ROLES.ADMIN)) { const result = await this.taskRepository.getTasksFromAccountId( @@ -54,9 +53,19 @@ export class TasksService { return { tasks: tasks, total: result.count }; } - if (roles.includes(USER_ROLES.AUTHOR)) { - throw new Error(`NOT IMPLEMENTED`); + const result = + await this.taskRepository.getTasksFromAuthorIdAndAccountId( + author_id, + account_id, + offset, + limit, + paramName ?? defaultParamName, + direction ?? defaultDirection, + status, + ); + const tasks = createTasks(result.tasks, result.permissions); + return { tasks: tasks, total: result.count }; } if (roles.includes(USER_ROLES.TYPIST)) { diff --git a/dictation_server/src/features/tasks/test/tasks.service.mock.ts b/dictation_server/src/features/tasks/test/tasks.service.mock.ts index b7b1ee4..7aa2173 100644 --- a/dictation_server/src/features/tasks/test/tasks.service.mock.ts +++ b/dictation_server/src/features/tasks/test/tasks.service.mock.ts @@ -5,6 +5,10 @@ import { User } from '../../../repositories/users/entity/user.entity'; import { UsersRepositoryService } from '../../../repositories/users/users.repository.service'; import { Task } from '../../../repositories/tasks/entity/task.entity'; import { CheckoutPermission } from '../../../repositories/checkout_permissions/entity/checkout_permission.entity'; +import { + SortDirection, + TaskListSortableAttribute, +} from '../../../common/types/sort'; export type TasksRepositoryMockValue = { getTasksFromAccountId: @@ -14,6 +18,13 @@ export type TasksRepositoryMockValue = { count: number; } | Error; + getTasksFromAuthorIdAndAccountId: + | { + tasks: Task[]; + permissions: CheckoutPermission[]; + count: number; + } + | Error; }; export type UsersRepositoryMockValue = { @@ -23,7 +34,10 @@ export type UsersRepositoryMockValue = { export const makeTasksServiceMock = async ( tasksRepositoryMockValue: TasksRepositoryMockValue, usersRepositoryMockValue: UsersRepositoryMockValue, -): Promise => { +): Promise<{ + tasksService: TasksService; + taskRepoService: TasksRepositoryService; +}> => { const module: TestingModule = await Test.createTestingModule({ providers: [TasksService], }) @@ -37,13 +51,14 @@ export const makeTasksServiceMock = async ( }) .compile(); - return module.get(TasksService); + return { + tasksService: module.get(TasksService), + taskRepoService: module.get(TasksRepositoryService), + }; }; -export const makeTasksRepositoryMock = ( - value:TasksRepositoryMockValue, -) => { - const { getTasksFromAccountId } = value; +export const makeTasksRepositoryMock = (value: TasksRepositoryMockValue) => { + const { getTasksFromAccountId, getTasksFromAuthorIdAndAccountId } = value; return { getTasksFromAccountId: getTasksFromAccountId instanceof Error @@ -58,6 +73,32 @@ export const makeTasksRepositoryMock = ( [] >() .mockResolvedValue(getTasksFromAccountId), + getTasksFromAuthorIdAndAccountId: + getTasksFromAuthorIdAndAccountId instanceof Error + ? jest + .fn< + Promise, + [ + string, + number, + number, + number, + TaskListSortableAttribute, + SortDirection, + string[], + ] + >() + .mockRejectedValue(getTasksFromAuthorIdAndAccountId) + : jest + .fn< + Promise<{ + tasks: Task[]; + permissions: CheckoutPermission[]; + count: number; + }>, + [] + >() + .mockResolvedValue(getTasksFromAuthorIdAndAccountId), }; }; @@ -75,125 +116,11 @@ export const makeUsersRepositoryMock = (value: UsersRepositoryMockValue) => { export const makeDefaultTasksRepositoryMockValue = (): TasksRepositoryMockValue => { return { - getTasksFromAccountId: { - tasks: [ - { - id: 1, - job_number: '00000001', - account_id: 1, - is_job_number_enabled: true, - audio_file_id: 1, - status: 'Uploaded', - priority: '00', - created_at: new Date('2023-01-01T01:01:01.000'), - option_items: [ - { - id: 1, - audio_file_id: 1, - label: "label01", - value: "value01", - }, - { - id: 2, - audio_file_id: 1, - label: "label02", - value: "value02", - }, - { - id: 3, - audio_file_id: 1, - label: "label03", - value: "value03", - }, - { - id: 4, - audio_file_id: 1, - label: "label04", - value: "value04", - }, - { - id: 5, - audio_file_id: 1, - label: "label05", - value: "value05", - }, - { - id: 6, - audio_file_id: 1, - label: "label06", - value: "value06", - }, - { - id: 7, - audio_file_id: 1, - label: "label07", - value: "value07", - }, - { - id: 8, - audio_file_id: 1, - label: "label08", - value: "value08", - }, - { - id: 9, - audio_file_id: 1, - label: "label09", - value: "value09", - }, - { - id: 10, - audio_file_id: 1, - label: "label10", - value: "value10", - }, - ], - file: { - id: 1, - account_id: 1, - owner_user_id: 1, - url: 'test/test.zip', - file_name: 'test.zip', - author_id: 'AUTHOR', - work_type_id: 'WorkType', - started_at: new Date('2023-01-01T01:01:01.000'), - duration: '123000', - finished_at: new Date('2023-01-01T01:01:01.000'), - uploaded_at: new Date('2023-01-01T01:01:01.000'), - file_size: 123000, - priority: '00', - audio_format: 'DS', - comment: 'comment', - is_encrypted: true, - }, - }, - ], - permissions: [ - { - id: 1, - task_id: 1, - user_id: 1, - user: { - id: 1, - account_id: 1, - external_id: 'userId', - role: 'typist', - accepted_terms_version: '', - email_verified: true, - auto_renew: true, - license_alert: true, - notification: true, - created_by: 'test', - created_at: new Date(), - updated_by: 'test', - updated_at: new Date(), - }, - }, - ], - count: 1, - }, + getTasksFromAccountId: defaultTasksRepositoryMockValue, + getTasksFromAuthorIdAndAccountId: defaultTasksRepositoryMockValue, }; }; + export const makeDefaultUsersRepositoryMockValue = (): UsersRepositoryMockValue => { const user1 = new User(); @@ -208,10 +135,130 @@ export const makeDefaultUsersRepositoryMockValue = user1.deleted_at = undefined; user1.created_by = 'test'; user1.created_at = new Date(); + user1.author_id = 'abcdef'; return { findUserByExternalId: user1, }; }; - - +const defaultTasksRepositoryMockValue: { + tasks: Task[]; + permissions: CheckoutPermission[]; + count: number; +} = { + tasks: [ + { + id: 1, + job_number: '00000001', + account_id: 1, + is_job_number_enabled: true, + audio_file_id: 1, + status: 'Uploaded', + priority: '00', + created_at: new Date('2023-01-01T01:01:01.000'), + option_items: [ + { + id: 1, + audio_file_id: 1, + label: 'label01', + value: 'value01', + }, + { + id: 2, + audio_file_id: 1, + label: 'label02', + value: 'value02', + }, + { + id: 3, + audio_file_id: 1, + label: 'label03', + value: 'value03', + }, + { + id: 4, + audio_file_id: 1, + label: 'label04', + value: 'value04', + }, + { + id: 5, + audio_file_id: 1, + label: 'label05', + value: 'value05', + }, + { + id: 6, + audio_file_id: 1, + label: 'label06', + value: 'value06', + }, + { + id: 7, + audio_file_id: 1, + label: 'label07', + value: 'value07', + }, + { + id: 8, + audio_file_id: 1, + label: 'label08', + value: 'value08', + }, + { + id: 9, + audio_file_id: 1, + label: 'label09', + value: 'value09', + }, + { + id: 10, + audio_file_id: 1, + label: 'label10', + value: 'value10', + }, + ], + file: { + id: 1, + account_id: 1, + owner_user_id: 1, + url: 'test/test.zip', + file_name: 'test.zip', + author_id: 'AUTHOR', + work_type_id: 'WorkType', + started_at: new Date('2023-01-01T01:01:01.000'), + duration: '123000', + finished_at: new Date('2023-01-01T01:01:01.000'), + uploaded_at: new Date('2023-01-01T01:01:01.000'), + file_size: 123000, + priority: '00', + audio_format: 'DS', + comment: 'comment', + is_encrypted: true, + }, + }, + ], + permissions: [ + { + id: 1, + task_id: 1, + user_id: 1, + user: { + id: 1, + account_id: 1, + external_id: 'userId', + role: 'typist', + accepted_terms_version: '', + email_verified: true, + auto_renew: true, + license_alert: true, + notification: true, + created_by: 'test', + created_at: new Date(), + updated_by: 'test', + updated_at: new Date(), + }, + }, + ], + count: 1, +}; diff --git a/dictation_server/src/repositories/tasks/tasks.repository.service.ts b/dictation_server/src/repositories/tasks/tasks.repository.service.ts index e0e2fca..30f0d3f 100644 --- a/dictation_server/src/repositories/tasks/tasks.repository.service.ts +++ b/dictation_server/src/repositories/tasks/tasks.repository.service.ts @@ -88,6 +88,72 @@ export class TasksRepositoryService { }); return value; } + /** + * 指定したauthor_idとaccount_idに紐づくTask関連情報の一覧を取得します + * @param author_id + * @param account_id + * @param offset + * @param limit + * @param sort_criteria + * @param direction + * @param status + * @returns tasks: タスク情報 / permissions:タスクに紐づくチェックアウト権限情報 / count: offset|limitを行わなかった場合の該当タスクの合計 + */ + async getTasksFromAuthorIdAndAccountId( + author_id: string, + account_id: number, + offset: number, + limit: number, + sort_criteria: TaskListSortableAttribute, + direction: SortDirection, + status: string[], + ): Promise<{ + tasks: Task[]; + permissions: CheckoutPermission[]; + count: number; + }> { + const order = makeOrder(sort_criteria, direction); + const value = await this.dataSource.transaction(async (entityManager) => { + const taskRepo = entityManager.getRepository(Task); + const count = await taskRepo.count({ + where: { + account_id: account_id, + status: In(status), + file: { author_id: author_id }, + }, + }); + + const tasks = await taskRepo.find({ + relations: { + file: true, + option_items: true, + typist_user: true, + }, + where: { + account_id: account_id, + status: In(status), + file: { author_id: author_id }, + }, + order: order, // 引数によってOrderに使用するパラメータを変更 + take: limit, + skip: offset, + }); + + const checkoutRepo = entityManager.getRepository(CheckoutPermission); + const taskIds = tasks.map((x) => x.id); + const permissions = await checkoutRepo.find({ + relations: { + user: true, + user_group: true, + }, + where: { + task_id: In(taskIds), + }, + }); + return { tasks, permissions, count }; + }); + return value; + } /** * 文字起こしタスクと音声ファイル、オプションアイテムを追加