import { Body, Controller, Get, Headers, HttpStatus, Param, Post, Query, Req, UseGuards, } from '@nestjs/common'; import { ApiResponse, ApiOperation, ApiTags, ApiBearerAuth, } from '@nestjs/swagger'; import { ErrorResponse } from '../../common/error/types/types'; import { Request } from 'express'; import { TasksService } from './tasks.service'; import { AudioNextRequest, AudioNextResponse, ChangeStatusRequest, ChangeStatusResponse, PostCheckoutPermissionRequest, PostCheckoutPermissionResponse, TasksRequest, TasksResponse, } from './types/types'; import { isSortDirection, isTaskListSortableAttribute, } from '../../common/types/sort'; import jwt from 'jsonwebtoken'; import { retrieveAuthorizationToken } from '../../common/http/helper'; import { AccessToken } from '../../common/token'; import { AuthGuard } from '../../common/guards/auth/authguards'; import { RoleGuard } from '../../common/guards/role/roleguards'; import { ADMIN_ROLES, USER_ROLES } from '../../constants'; @ApiTags('tasks') @Controller('tasks') export class TasksController { constructor(private readonly taskService: TasksService) {} @ApiResponse({ status: HttpStatus.OK, type: TasksResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '不正なパラメータ', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'getTasks', description: '音声ファイル・文字起こしタスク情報をページ指定して取得します', }) @ApiBearerAuth() @UseGuards(AuthGuard) @Get() async getTasks( @Req() req, @Query() body: TasksRequest, ): Promise { const accessToken = retrieveAuthorizationToken(req); const decodedToken = jwt.decode(accessToken, { json: true }) as AccessToken; const { limit, offset, status } = body; const paramName = isTaskListSortableAttribute(body.paramName) ? body.paramName : undefined; const direction = isSortDirection(body.direction) ? body.direction : undefined; const { tasks, total } = await this.taskService.getTasksFromAccountId( decodedToken, offset, limit, status?.split(',') ?? [], paramName, direction, ); return { tasks, total, limit, offset }; } @Get('next') @ApiResponse({ status: HttpStatus.OK, type: AudioNextResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '不正なパラメータ', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'getNextAudioFile', description: '指定した文字起こしタスクの次のタスクに紐づく音声ファイルIDを取得します', }) @ApiBearerAuth() async getNextAudioFile( @Headers() headers, @Query() body: AudioNextRequest, ): Promise { const { endedFileId } = body; console.log(endedFileId); return { nextFileId: 1234 }; } @Post(':audioFileId/checkout') @ApiResponse({ status: HttpStatus.OK, type: ChangeStatusResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '不正なパラメータ', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.NOT_FOUND, description: '指定したIDの音声ファイルが存在しない場合', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'checkout', description: '指定した文字起こしタスクをチェックアウトします(ステータスをInprogressにします)', }) @ApiBearerAuth() async checkout( @Headers() headers, @Param() params: ChangeStatusRequest, ): Promise { const { audioFileId } = params; console.log(audioFileId); return {}; } @Post(':audioFileId/checkin') @ApiResponse({ status: HttpStatus.OK, type: ChangeStatusResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '不正なパラメータ', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.NOT_FOUND, description: '指定したIDの音声ファイルが存在しない場合', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'checkin', description: '指定した文字起こしタスクをチェックインします(ステータスをFinishedにします)', }) @ApiBearerAuth() async checkin( @Headers() headers, @Param() params: ChangeStatusRequest, ): Promise { const { audioFileId } = params; console.log(audioFileId); return {}; } @Post(':audioFileId/cancel') @ApiResponse({ status: HttpStatus.OK, type: ChangeStatusResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '不正なパラメータ', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.NOT_FOUND, description: '指定したIDの音声ファイルが存在しない場合', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'cancel', description: '指定した文字起こしタスクをキャンセルします(ステータスをUploadedにします)', }) @ApiBearerAuth() async cancel( @Headers() headers, @Param() params: ChangeStatusRequest, ): Promise { const { audioFileId } = params; console.log(audioFileId); return {}; } @Post(':audioFileId/suspend') @ApiResponse({ status: HttpStatus.OK, type: ChangeStatusResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '不正なパラメータ', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.NOT_FOUND, description: '指定したIDの音声ファイルが存在しない場合', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'suspend', description: '指定した文字起こしタスクを一時中断します(ステータスをPendingにします)', }) @ApiBearerAuth() async suspend( @Headers() headers, @Param() params: ChangeStatusRequest, ): Promise { const { audioFileId } = params; console.log(audioFileId); return {}; } @Post(':audioFileId/send-back') @ApiResponse({ status: HttpStatus.OK, type: ChangeStatusResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '不正なパラメータ', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.NOT_FOUND, description: '指定したIDの音声ファイルが存在しない場合', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'sendBack', description: '指定した文字起こしタスクを差し戻します(ステータスをPendingにします)', }) @ApiBearerAuth() async sendBack( @Headers() headers, @Param() params: ChangeStatusRequest, ): Promise { const { audioFileId } = params; console.log(audioFileId); return {}; } @Post(':audioFileId/backup') @ApiResponse({ status: HttpStatus.OK, type: ChangeStatusResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '不正なパラメータ', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.NOT_FOUND, description: '指定したIDの音声ファイルが存在しない場合', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'backup', description: '指定した文字起こしタスクをバックアップします(ステータスをBackupにします)', }) @ApiBearerAuth() async backup( @Headers() headers, @Param() params: ChangeStatusRequest, ): Promise { const { audioFileId } = params; console.log(audioFileId); return {}; } @Post(':audioFileId/checkout-permission') @ApiResponse({ status: HttpStatus.OK, type: PostCheckoutPermissionResponse, description: '成功時のレスポンス', }) @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: '不正なパラメータ(タスクのステータス不正、指定ユーザー不正など)', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.NOT_FOUND, description: '指定したIDの音声ファイルが存在しない', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.UNAUTHORIZED, description: '認証エラー', type: ErrorResponse, }) @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: '想定外のサーバーエラー', type: ErrorResponse, }) @ApiOperation({ operationId: 'changeCheckoutPermission', description: '指定した文字起こしタスクのチェックアウト候補を変更します。', }) @ApiBearerAuth() @UseGuards(AuthGuard) @UseGuards( RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN, USER_ROLES.AUTHOR] }), ) async changeCheckoutPermission( @Req() req: Request, @Param(`audioFileId`) audioFileId: number, @Body() body: PostCheckoutPermissionRequest, ): Promise { const { assignees } = body; console.log(req.header('Authorization')); console.log(audioFileId); console.log(assignees); return {}; } }