makabe.t 794099f37d Merged PR 292: 外部連携APIにログを入れ込む(強化)
## 概要
[Task2294: 外部連携APIにログを入れ込む(強化)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2294)

- 外部連携APIのログを強化しました。
  - contextオブジェクトで操作者情報を渡すようにしています。
- ログポリシーに従って追加しています。
  - [ログポリシー](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/OMDSDictation/_wiki/wikis/OMDSDictation_wiki/223/%E3%83%AD%E3%82%B0%E3%83%9D%E3%83%AA%E3%82%B7%E3%83%BC)

## レビューポイント
- 出力内容に過不足はないか
- ログ追加対象に過不足はないか。
- contextで操作者情報を渡しているが想定通りか

## UIの変更
- なし

## 動作確認状況
- ローカルで確認
2023-08-02 01:07:02 +00:00

262 lines
7.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
Body,
Controller,
Get,
HttpStatus,
Post,
Query,
Req,
UseGuards,
} from '@nestjs/common';
import {
ApiBearerAuth,
ApiOperation,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import jwt from 'jsonwebtoken';
import { AccessToken } from '../../common/token';
import { ErrorResponse } from '../../common/error/types/types';
import { FilesService } from './files.service';
import {
AudioDownloadLocationRequest,
AudioDownloadLocationResponse,
AudioUploadFinishedRequest,
AudioUploadFinishedResponse,
AudioUploadLocationRequest,
AudioUploadLocationResponse,
TemplateDownloadLocationRequest,
TemplateDownloadLocationResponse,
} from './types/types';
import { AuthGuard } from '../../common/guards/auth/authguards';
import { RoleGuard } from '../../common/guards/role/roleguards';
import { USER_ROLES } from '../../constants';
import { retrieveAuthorizationToken } from '../../common/http/helper';
import { Request } from 'express';
import { makeContext } from '../../common/log';
@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.UNAUTHORIZED,
description: '認証エラー',
type: ErrorResponse,
})
@ApiResponse({
status: HttpStatus.INTERNAL_SERVER_ERROR,
description: '想定外のサーバーエラー',
type: ErrorResponse,
})
@ApiOperation({
operationId: 'uploadFinished',
description:
'アップロードが完了した音声ファイルの情報を登録し、文字起こしタスクを生成します',
})
@ApiBearerAuth()
@UseGuards(AuthGuard)
@UseGuards(RoleGuard.requireds({ roles: [USER_ROLES.AUTHOR] }))
@Post('audio/upload-finished')
async uploadFinished(
@Req() req: Request,
@Body() body: AudioUploadFinishedRequest,
): Promise<AudioUploadFinishedResponse> {
const token = retrieveAuthorizationToken(req);
const accessToken = jwt.decode(token, { json: true }) as AccessToken;
const context = makeContext(accessToken.userId);
const {
url,
authorId,
fileName,
duration,
createdDate,
finishedDate,
uploadedDate,
fileSize,
priority,
audioFormat,
comment,
workType,
optionItemList,
isEncrypted,
} = body;
const res = await this.filesService.uploadFinished(
context,
accessToken.userId,
url,
authorId,
fileName,
duration,
createdDate,
finishedDate,
uploadedDate,
fileSize,
priority,
audioFormat,
comment,
workType,
optionItemList,
isEncrypted,
);
return { jobNumber: res.jobNumber };
}
@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',
description:
'ログイン中ユーザー用のBlob Storage上の音声ファイルのアップロード先アクセスURLを取得します',
})
@ApiBearerAuth()
@UseGuards(AuthGuard)
@UseGuards(RoleGuard.requireds({ roles: [USER_ROLES.AUTHOR] }))
async uploadLocation(
@Req() req: Request,
// クエリパラメータ AudioUploadLocationRequest は空であるため内部で使用しない。
// 使用しないことを宣言するために先頭にプレフィックス_アンダースコアをつけている
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@Query() _query: AudioUploadLocationRequest,
): Promise<AudioUploadLocationResponse> {
const token = retrieveAuthorizationToken(req);
const accessToken = jwt.decode(token, { json: true }) as AccessToken;
const context = makeContext(accessToken.userId);
const url = await this.filesService.publishUploadSas(context, accessToken);
return { url };
}
@Get('audio/download-location')
@ApiResponse({
status: HttpStatus.OK,
type: AudioDownloadLocationResponse,
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: 'downloadLocation',
description:
'指定した音声ファイルのBlob Storage上のダウンロード先アクセスURLを取得します',
})
@ApiBearerAuth()
@UseGuards(AuthGuard)
@UseGuards(
RoleGuard.requireds({ roles: [USER_ROLES.AUTHOR, USER_ROLES.TYPIST] }),
)
async downloadLocation(
@Req() req: Request,
@Query() body: AudioDownloadLocationRequest,
): Promise<AudioDownloadLocationResponse> {
const { audioFileId } = body;
const token = retrieveAuthorizationToken(req);
const accessToken = jwt.decode(token, { json: true }) as AccessToken;
const context = makeContext(accessToken.userId);
const url = await this.filesService.publishAudioFileDownloadSas(
context,
accessToken.userId,
audioFileId,
);
return { url };
}
@Get('template/download-location')
@ApiResponse({
status: HttpStatus.OK,
type: TemplateDownloadLocationResponse,
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: 'downloadTemplateLocation',
description:
'指定した音声ファイルに対応したテンプレートファイルのBlob Storage上のダウンロード先アクセスURLを取得します',
})
@ApiBearerAuth()
@UseGuards(AuthGuard)
@UseGuards(
RoleGuard.requireds({ roles: [USER_ROLES.AUTHOR, USER_ROLES.TYPIST] }),
)
async downloadTemplateLocation(
@Req() req: Request,
@Query() body: TemplateDownloadLocationRequest,
): Promise<TemplateDownloadLocationResponse> {
const { audioFileId } = body;
const token = retrieveAuthorizationToken(req);
const accessToken = jwt.decode(token, { json: true }) as AccessToken;
const context = makeContext(accessToken.userId);
const url = await this.filesService.publishTemplateFileDownloadSas(
context,
accessToken.userId,
audioFileId,
);
return { url };
}
}