Merged PR 89: IF実装(音声ファイル、タスク情報取得API)

## 概要
[Task1647: IF実装(音声ファイル、タスク情報取得API)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/1647)

- 以下の外部連携APIのIFを実装しました
  - 音声ファイル、タスク情報取得API
- blob、taskフォルダにあったAPI定義をfilesフォルダに集めました。

## レビューポイント
- フォルダの変更に問題はないか
- 音声ファイル、タスク情報取得APIのパスを`GET /files/audio/task-info`としましたがAPIのパスとして適切でしょうか?

## UIの変更
- なし
## 動作確認状況
- ローカルのSwaggerで確認
This commit is contained in:
makabe.t 2023-04-28 08:12:05 +00:00
parent 0bcb0b071b
commit 085f41134a
19 changed files with 1464 additions and 856 deletions

File diff suppressed because it is too large Load Diff

View File

@ -22,10 +22,12 @@ import { UsersRepositoryModule } from './repositories/users/users.repository.mod
import { NotificationhubModule } from './gateways/notificationhub/notificationhub.module';
import { NotificationhubService } from './gateways/notificationhub/notificationhub.service';
import { NotificationModule } from './features/notification/notification.module';
import { BlobModule } from './features/blob/blob.module';
import { TaskService } from './features/task/task.service';
import { TaskModule } from './features/task/task.module';
import { TaskController } from './features/task/task.controller';
import { FilesModule } from './features/files/files.module';
import { FilesController } from './features/files/files.controller';
import { FilesService } from './features/files/files.service';
import { TasksService } from './features/tasks/tasks.service';
import { TasksController } from './features/tasks/tasks.controller';
import { TasksModule } from './features/tasks/tasks.module';
@Module({
imports: [
@ -40,8 +42,10 @@ import { TaskController } from './features/task/task.controller';
CryptoModule,
AdB2cModule,
AccountsModule,
TaskModule,
UsersModule,
UsersModule,
FilesModule,
TasksModule,
UsersModule,
SendGridModule,
AccountsRepositoryModule,
UsersRepositoryModule,
@ -61,23 +65,23 @@ import { TaskController } from './features/task/task.controller';
}),
NotificationModule,
NotificationhubModule,
BlobModule,
TaskModule,
],
controllers: [
HealthController,
AuthController,
AccountsController,
TaskController,
UsersController,
UsersController,
FilesController,
TasksController,
UsersController,
],
providers: [
AuthService,
AccountsService,
TaskService,
UsersService,
NotificationhubService,
TaskService,
FilesService,
TasksService,
],
})
export class AppModule {

View File

@ -1,23 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { BlobController } from './blob.controller';
import { BlobService } from './blob.service';
describe('BlobController', () => {
let controller: BlobController;
const mockBlobService = {};
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [BlobController],
providers: [BlobService],
})
.overrideProvider(BlobService)
.useValue(mockBlobService)
.compile();
controller = module.get<BlobController>(BlobController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@ -1,110 +0,0 @@
import { Controller, Get, Headers, HttpStatus, Query } from '@nestjs/common';
import {
ApiResponse,
ApiOperation,
ApiBearerAuth,
ApiTags,
} from '@nestjs/swagger';
import { ErrorResponse } from '../../common/error/types/types';
import { BlobService } from './blob.service';
import {
AudioUploadLocationResponse,
AudioUploadLocationRequest,
AudioDownloadLocationResponse,
AudioDownloadLocationRequest,
TemplateDownloadLocationResponse,
TemplateDownloadLocationRequest,
} from './types/types';
@ApiTags('files')
@Controller('files')
export class BlobController {
constructor(private readonly blobService: BlobService) {}
@Get('audio/upload-location')
@ApiResponse({
status: HttpStatus.OK,
type: AudioUploadLocationResponse,
description: '成功時のレスポンス',
})
@ApiResponse({
status: HttpStatus.UNAUTHORIZED,
description: '認証エラー',
type: ErrorResponse,
})
@ApiResponse({
status: HttpStatus.INTERNAL_SERVER_ERROR,
description: '想定外のサーバーエラー',
type: ErrorResponse,
})
@ApiOperation({ operationId: 'uploadLocation' })
@ApiBearerAuth()
async uploadLocation(
@Headers() headers,
@Query() query: AudioUploadLocationRequest,
): Promise<AudioUploadLocationResponse> {
const {} = query;
// コンテナ作成処理の前にアクセストークンの認証を行う
// アップロード先を決定する国情報はトークンから取得する想定
return { url: '' };
}
@Get('audio/download-location')
@ApiResponse({
status: HttpStatus.OK,
type: AudioDownloadLocationResponse,
description: '成功時のレスポンス',
})
@ApiResponse({
status: HttpStatus.UNAUTHORIZED,
description: '認証エラー',
type: ErrorResponse,
})
@ApiResponse({
status: HttpStatus.INTERNAL_SERVER_ERROR,
description: '想定外のサーバーエラー',
type: ErrorResponse,
})
@ApiOperation({ operationId: 'downloadLocation' })
@ApiBearerAuth()
async downloadLocation(
@Headers() headers,
@Query() body: AudioDownloadLocationRequest,
): Promise<AudioDownloadLocationResponse> {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { id } = body;
// コンテナ作成処理の前にアクセストークンの認証を行う
//
return { url: '' };
}
@Get('template/download-location')
@ApiResponse({
status: HttpStatus.OK,
type: TemplateDownloadLocationResponse,
description: '成功時のレスポンス',
})
@ApiResponse({
status: HttpStatus.UNAUTHORIZED,
description: '認証エラー',
type: ErrorResponse,
})
@ApiResponse({
status: HttpStatus.INTERNAL_SERVER_ERROR,
description: '想定外のサーバーエラー',
type: ErrorResponse,
})
@ApiOperation({ operationId: 'downloadTemplateLocation' })
@ApiBearerAuth()
async downloadTemplateLocation(
@Headers() headers,
@Query() body: TemplateDownloadLocationRequest,
): Promise<TemplateDownloadLocationResponse> {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { audioFileId } = body;
// コンテナ作成処理の前にアクセストークンの認証を行う
return { url: '' };
}
}

View File

@ -1,9 +0,0 @@
import { Module } from '@nestjs/common';
import { BlobService } from './blob.service';
import { BlobController } from './blob.controller';
@Module({
providers: [BlobService],
controllers: [BlobController],
})
export class BlobModule {}

View File

@ -1,28 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
export class AudioUploadLocationRequest {}
export class AudioUploadLocationResponse {
@ApiProperty()
url: string;
}
export class AudioDownloadLocationRequest {
@ApiProperty({ description: '音声ファイル情報をDBから取得するためのID' })
id: string;
}
export class AudioDownloadLocationResponse {
@ApiProperty()
url: string;
}
export class TemplateDownloadLocationRequest {
@ApiProperty({ description: '文字起こし対象の音声ファイルID' })
audioFileId: string;
}
export class TemplateDownloadLocationResponse {
@ApiProperty()
url: string;
}

View File

@ -1,4 +1,12 @@
import { Controller, Get, Headers, HttpStatus, Query } from '@nestjs/common';
import {
Body,
Controller,
Get,
Headers,
HttpStatus,
Post,
Query,
} from '@nestjs/common';
import {
ApiResponse,
ApiOperation,
@ -7,13 +15,136 @@ import {
} from '@nestjs/swagger';
import { ErrorResponse } from '../../common/error/types/types';
import { FilesService } from './files.service';
import { AudioNextRequest, AudioNextResponse } from './types/types';
import {
AudioDownloadLocationRequest,
AudioDownloadLocationResponse,
AudioNextRequest,
AudioNextResponse,
AudioUploadFinishedRequest,
AudioUploadFinishedResponse,
AudioUploadLocationRequest,
AudioUploadLocationResponse,
TemplateDownloadLocationRequest,
TemplateDownloadLocationResponse,
} from './types/types';
@ApiTags('files')
@Controller('files')
export class FilesController {
constructor(private readonly filesService: FilesService) {}
@ApiResponse({
status: HttpStatus.OK,
type: AudioUploadFinishedResponse,
description: '成功時のレスポンス',
})
@ApiResponse({
status: HttpStatus.BAD_REQUEST,
description: '不正なパラメータ',
type: ErrorResponse,
})
@ApiResponse({
status: HttpStatus.INTERNAL_SERVER_ERROR,
description: '想定外のサーバーエラー',
type: ErrorResponse,
})
@ApiOperation({ operationId: 'createTask' })
@Post('audio/upload-finished')
async uploadFinished(
@Body() body: AudioUploadFinishedRequest,
): Promise<AudioUploadFinishedResponse> {
console.log(body);
return { jobNumber: '00000001' };
}
@Get('audio/upload-location')
@ApiResponse({
status: HttpStatus.OK,
type: AudioUploadLocationResponse,
description: '成功時のレスポンス',
})
@ApiResponse({
status: HttpStatus.UNAUTHORIZED,
description: '認証エラー',
type: ErrorResponse,
})
@ApiResponse({
status: HttpStatus.INTERNAL_SERVER_ERROR,
description: '想定外のサーバーエラー',
type: ErrorResponse,
})
@ApiOperation({ operationId: 'uploadLocation' })
@ApiBearerAuth()
async uploadLocation(
@Headers() headers,
@Query() query: AudioUploadLocationRequest,
): Promise<AudioUploadLocationResponse> {
const {} = query;
// コンテナ作成処理の前にアクセストークンの認証を行う
// アップロード先を決定する国情報はトークンから取得する想定
return { url: '' };
}
@Get('audio/download-location')
@ApiResponse({
status: HttpStatus.OK,
type: AudioDownloadLocationResponse,
description: '成功時のレスポンス',
})
@ApiResponse({
status: HttpStatus.UNAUTHORIZED,
description: '認証エラー',
type: ErrorResponse,
})
@ApiResponse({
status: HttpStatus.INTERNAL_SERVER_ERROR,
description: '想定外のサーバーエラー',
type: ErrorResponse,
})
@ApiOperation({ operationId: 'downloadLocation' })
@ApiBearerAuth()
async downloadLocation(
@Headers() headers,
@Query() body: AudioDownloadLocationRequest,
): Promise<AudioDownloadLocationResponse> {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { audioFileId } = body;
// コンテナ作成処理の前にアクセストークンの認証を行う
//
return { url: '' };
}
@Get('template/download-location')
@ApiResponse({
status: HttpStatus.OK,
type: TemplateDownloadLocationResponse,
description: '成功時のレスポンス',
})
@ApiResponse({
status: HttpStatus.UNAUTHORIZED,
description: '認証エラー',
type: ErrorResponse,
})
@ApiResponse({
status: HttpStatus.INTERNAL_SERVER_ERROR,
description: '想定外のサーバーエラー',
type: ErrorResponse,
})
@ApiOperation({ operationId: 'downloadTemplateLocation' })
@ApiBearerAuth()
async downloadTemplateLocation(
@Headers() headers,
@Query() body: TemplateDownloadLocationRequest,
): Promise<TemplateDownloadLocationResponse> {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { audioFileId } = body;
// コンテナ作成処理の前にアクセストークンの認証を行う
return { url: '' };
}
@Get('audio/next')
@ApiResponse({
status: HttpStatus.OK,
@ -39,6 +170,6 @@ export class FilesController {
const { endedFileId } = body;
console.log(endedFileId);
return { nextFileId: '1234' };
return { nextFileId: 1234 };
}
}

View File

@ -2,10 +2,86 @@ import { ApiProperty } from '@nestjs/swagger';
export class AudioNextRequest {
@ApiProperty({ description: '文字起こし完了したタスクの音声ファイルID' })
endedFileId: string;
endedFileId: number;
}
export class AudioNextResponse {
@ApiProperty({ description: 'OMDS Cloud上の次の音声ファイルID' })
nextFileId: string;
@ApiProperty({
description: 'ODMS Cloud上の次の音声ファイルID存在しなければ空文字',
})
nextFileId: number;
}
export class AudioUploadLocationRequest {}
export class AudioUploadLocationResponse {
@ApiProperty()
url: string;
}
export class AudioDownloadLocationRequest {
@ApiProperty({ description: '音声ファイル情報をDBから取得するためのID' })
audioFileId: number;
}
export class AudioDownloadLocationResponse {
@ApiProperty()
url: string;
}
export class TemplateDownloadLocationRequest {
@ApiProperty({ description: '文字起こし対象の音声ファイルID' })
audioFileId: number;
}
export class TemplateDownloadLocationResponse {
@ApiProperty()
url: string;
}
export class AudioUploadFinishedRequest {
@ApiProperty({ description: 'アップロード先Blob Storage(ファイル名含む)' })
url: string;
@ApiProperty({ description: '自分自身(ログイン認証)したAuthorID' })
authorId: string;
@ApiProperty({ description: '音声ファイル名' })
fileName: string;
@ApiProperty({
description: '音声ファイルの録音時間yyyy-mm-ddThh:mm:ss.sss',
})
duration: string;
@ApiProperty({
description:
'音声ファイルの録音作成日時(開始日時)yyyy-mm-ddThh:mm:ss.sss',
})
createdDate: string;
@ApiProperty({
description: '音声ファイルの録音作成終了日時yyyy-mm-ddThh:mm:ss.sss',
})
completedDate: string;
@ApiProperty({
description: '音声ファイルのアップロード日時yyyy-mm-ddThh:mm:ss.sss',
})
uploadedDate: string;
@ApiProperty()
fileSize: string;
@ApiProperty({ description: '優先度 "00":Normal / "01":High' })
priority: string;
@ApiProperty({ description: '録音形式: DSS/DS2(SP)/DS2(QP)' })
audioFormat: string;
@ApiProperty()
comment: string;
@ApiProperty()
workType: string;
@ApiProperty({ minLength: 1, maxLength: 16 })
optionItemLabel: string;
@ApiProperty({ minLength: 1, maxLength: 20 })
optionItemValue: string;
@ApiProperty()
isEncrypted: boolean;
}
export class AudioUploadFinishedResponse {
@ApiProperty({ description: '8桁固定の数字' })
jobNumber: string;
}

View File

@ -1,24 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { TaskController } from './task.controller';
import { TaskService } from './task.service';
describe('TaskController', () => {
let controller: TaskController;
const mockTaskervice = {};
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [TaskController],
providers: [TaskService],
})
.overrideProvider(TaskService)
.useValue(mockTaskervice)
.compile();
controller = module.get<TaskController>(TaskController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@ -1,10 +0,0 @@
import { Module } from '@nestjs/common';
import { TaskController } from './task.controller';
import { TaskService } from './task.service';
@Module({
imports: [],
controllers: [TaskController],
providers: [TaskService],
})
export class TaskModule {}

View File

@ -1,21 +0,0 @@
import { Test, TestingModule } from '@nestjs/testing';
import { TaskService } from './task.service';
describe('TaskService', () => {
let service: TaskService;
const mockTaskService = {};
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [TaskService],
})
.overrideProvider(TaskService)
.useValue(mockTaskService)
.compile();
service = module.get<TaskService>(TaskService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -1,4 +0,0 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class TaskService {}

View File

@ -1,9 +0,0 @@
import { ApiProperty } from '@nestjs/swagger';
export class ChangeStatusRequest {
@ApiProperty({ description: 'OMDS Cloud上の音声ファイルID' })
audioFileId: string;
}
export class ChangeStatusResponse {}

View File

@ -0,0 +1,23 @@
import { Test, TestingModule } from '@nestjs/testing';
import { TasksController } from './tasks.controller';
import { TasksService } from './tasks.service';
describe('TasksController', () => {
let controller: TasksController;
const mockTaskService = {};
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [TasksController],
providers: [TasksService],
})
.overrideProvider(TasksService)
.useValue(mockTaskService)
.compile();
controller = module.get<TasksController>(TasksController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@ -1,19 +1,65 @@
import { Body, Controller, Headers, HttpStatus, Post } from '@nestjs/common';
import {
ApiBearerAuth,
ApiOperation,
Controller,
Get,
Headers,
HttpStatus,
Param,
Post,
Query,
} from '@nestjs/common';
import {
ApiResponse,
ApiOperation,
ApiBearerAuth,
ApiTags,
} from '@nestjs/swagger';
import { TaskService } from './task.service';
import { ChangeStatusRequest, ChangeStatusResponse } from './types/types';
import { ErrorResponse } from '../../common/error/types/types';
import { TasksService } from './tasks.service';
import {
ChangeStatusRequest,
ChangeStatusResponse,
TasksRequest,
TasksResponse,
} from './types/types';
@ApiTags('task')
@Controller('task')
export class TaskController {
constructor(private readonly taskService: TaskService) {}
@Post('checkout')
@ApiTags('tasks')
@Controller('tasks')
export class TasksController {
constructor(private readonly taskService: TasksService) {}
@ApiResponse({
status: HttpStatus.OK,
type: TasksResponse,
description: '成功時のレスポンス',
})
@ApiResponse({
status: HttpStatus.UNAUTHORIZED,
description: '認証エラー',
type: ErrorResponse,
})
@ApiResponse({
status: HttpStatus.INTERNAL_SERVER_ERROR,
description: '想定外のサーバーエラー',
type: ErrorResponse,
})
@ApiOperation({ operationId: 'getTasks' })
@ApiBearerAuth()
@Get()
async getTasks(
@Headers() headers,
@Query() body: TasksRequest,
): Promise<TasksResponse> {
console.log(headers);
console.log(body);
return {
pageNumber: 1,
pageSize: 1,
total: 0,
tasks: [],
};
}
@Post(':audioFileId/checkout')
@ApiResponse({
status: HttpStatus.OK,
type: ChangeStatusResponse,
@ -38,14 +84,15 @@ export class TaskController {
@ApiBearerAuth()
async checkout(
@Headers() headers,
@Body() body: ChangeStatusRequest,
@Param() params: ChangeStatusRequest,
): Promise<ChangeStatusResponse> {
const {} = body;
const { audioFileId } = params;
console.log(audioFileId);
return {};
}
@Post('checkin')
@Post(':audioFileId/checkin')
@ApiResponse({
status: HttpStatus.OK,
type: ChangeStatusResponse,
@ -70,14 +117,15 @@ export class TaskController {
@ApiBearerAuth()
async checkin(
@Headers() headers,
@Body() body: ChangeStatusRequest,
@Param() params: ChangeStatusRequest,
): Promise<ChangeStatusResponse> {
const {} = body;
const { audioFileId } = params;
console.log(audioFileId);
return {};
}
@Post('cancel')
@Post(':audioFileId/cancel')
@ApiResponse({
status: HttpStatus.OK,
type: ChangeStatusResponse,
@ -102,14 +150,15 @@ export class TaskController {
@ApiBearerAuth()
async cancel(
@Headers() headers,
@Body() body: ChangeStatusRequest,
@Param() params: ChangeStatusRequest,
): Promise<ChangeStatusResponse> {
const {} = body;
const { audioFileId } = params;
console.log(audioFileId);
return {};
}
@Post('suspend')
@Post(':audioFileId/suspend')
@ApiResponse({
status: HttpStatus.OK,
type: ChangeStatusResponse,
@ -134,14 +183,15 @@ export class TaskController {
@ApiBearerAuth()
async suspend(
@Headers() headers,
@Body() body: ChangeStatusRequest,
@Param() params: ChangeStatusRequest,
): Promise<ChangeStatusResponse> {
const {} = body;
const { audioFileId } = params;
console.log(audioFileId);
return {};
}
@Post('send-back')
@Post(':audioFileId/send-back')
@ApiResponse({
status: HttpStatus.OK,
type: ChangeStatusResponse,
@ -166,14 +216,15 @@ export class TaskController {
@ApiBearerAuth()
async sendBack(
@Headers() headers,
@Body() body: ChangeStatusRequest,
@Param() params: ChangeStatusRequest,
): Promise<ChangeStatusResponse> {
const {} = body;
const { audioFileId } = params;
console.log(audioFileId);
return {};
}
// TODO 操作としてarchiveの方が適切かもしれない
@Post('backup')
@Post(':audioFileId/backup')
@ApiResponse({
status: HttpStatus.OK,
type: ChangeStatusResponse,
@ -198,9 +249,10 @@ export class TaskController {
@ApiBearerAuth()
async backup(
@Headers() headers,
@Body() body: ChangeStatusRequest,
@Param() params: ChangeStatusRequest,
): Promise<ChangeStatusResponse> {
const {} = body;
const { audioFileId } = params;
console.log(audioFileId);
return {};
}

View File

@ -0,0 +1,9 @@
import { Module } from '@nestjs/common';
import { TasksService } from './tasks.service';
import { TasksController } from './tasks.controller';
@Module({
providers: [TasksService],
controllers: [TasksController],
})
export class TasksModule {}

View File

@ -1,15 +1,15 @@
import { Test, TestingModule } from '@nestjs/testing';
import { BlobService } from './blob.service';
import { TasksService } from './tasks.service';
describe('BlobService', () => {
let service: BlobService;
describe('TasksService', () => {
let service: TasksService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [BlobService],
providers: [TasksService],
}).compile();
service = module.get<BlobService>(BlobService);
service = module.get<TasksService>(TasksService);
});
it('should be defined', () => {

View File

@ -1,4 +1,4 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class BlobService {}
export class TasksService {}

View File

@ -0,0 +1,124 @@
import { ApiProperty } from '@nestjs/swagger';
export class TasksRequest {
@ApiProperty({
minimum: 1,
description:
'ページ番号(ページサイズごとに区切った何ページ目を取得するか)',
})
pageNumber: number;
@ApiProperty({
minimum: 1,
description: 'ページサイズ(一度に何件のタスクを取得するか)',
})
pageSize: number;
}
export class Typist {
@ApiProperty({
required: false,
description: 'TypistIDTypistIDかTypistGroupIDのどちらかに値が入る',
})
typistUserId?: number | undefined;
@ApiProperty({
required: false,
description: 'TypistGroupIDTypistGroupIDかTypistIDのどちらかに値が入る',
})
typistGroupId?: number | undefined;
@ApiProperty({ description: 'Typist名 / TypistGroup名' })
typistName: string;
}
export class Task {
@ApiProperty({ description: 'ODMS Cloud上の音声ファイルID' })
audioFileId: number;
@ApiProperty({ description: 'AuthorID' })
authorId: string;
@ApiProperty()
workType: string;
@ApiProperty({ minLength: 1, maxLength: 16 })
optionItemLabel: string;
@ApiProperty({ minLength: 1, maxLength: 20 })
optionItemValue: string;
@ApiProperty({ description: 'アップロード先Blob Storage(ファイル名含む)' })
url: string;
@ApiProperty({ description: '音声ファイル名' })
fileName: string;
@ApiProperty({
description: '音声ファイルの録音時間yyyy-mm-ddThh:mm:ss.sss',
})
audioDuration: string;
@ApiProperty({
description: '音声ファイルの録音開始日時yyyy-mm-ddThh:mm:ss.sss',
})
audioCreatedDate: string;
@ApiProperty({
description: '音声ファイルの録音終了日時yyyy-mm-ddThh:mm:ss.sss',
})
audioFinishedDate: string;
@ApiProperty({
description: '音声ファイルのアップロード日時yyyy-mm-ddThh:mm:ss.sss',
})
audioUploadedDate: string;
@ApiProperty({ description: '音声ファイルのファイルサイズ' })
fileSize: string;
@ApiProperty({ description: '音声ファイルの優先度 "00":Normal / "01":High' })
priority: string;
@ApiProperty({ description: '録音形式: DSS/DS2(SP)/DS2(QP)' })
audioFormat: string;
@ApiProperty({ description: 'コメント' })
comment: string;
@ApiProperty()
isEncrypted: boolean;
@ApiProperty({ description: 'JOBナンバー' })
jobNumber: string;
@ApiProperty({
required: false,
description: '割り当てられたユーザー',
})
typist?: Typist | undefined;
@ApiProperty({
type: [Typist],
description:
'文字起こしに着手できる(チェックアウト可能な)、タスクにアサインされているグループ/個人の一覧',
})
assignees: Typist[];
@ApiProperty({
description:
'音声ファイルのファイルステータス 1:Uploaded(Cancel) / 2:Pending / 3:InProgress / 4:Finished / 5:Backup',
})
status: number;
@ApiProperty({ description: '文字起こし開始日時yyyy-mm-ddThh:mm:ss.sss' })
transcriptionStartedDate: string;
@ApiProperty({ description: '文字起こし終了日時yyyy-mm-ddThh:mm:ss.sss' })
transcriptionFinishedDate: string;
}
export class TasksResponse {
@ApiProperty({
description:
'ページ番号(ページサイズごとに区切った何ページ目か。 ページ番号が存在しない場合は末尾のページ)',
})
pageNumber: number;
@ApiProperty({
description: 'ページサイズ(一度に何件のタスクを取得するか)',
})
pageSize: number;
@ApiProperty({
description: 'タスクの総件数',
})
total: number;
@ApiProperty({
type: [Task],
description: '音声ファイル/タスク一覧',
})
tasks: Task[];
}
export class ChangeStatusRequest {
@ApiProperty({ description: 'ODMS Cloud上の音声ファイルID' })
audioFileId: number;
}
export class ChangeStatusResponse {}