Merged PR 418: API IF実装
## 概要 [Task2649: API IF実装](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2649) - テンプレートファイル周りで以下のAPIIFを実装し、OpenAPIを更新しました。 - テンプレートファイル一覧取得API - テンプレートファイルアップロード先取得API - テンプレートファイルアップロード完了API ## レビューポイント - 各APIのパスは適切か - パラメータは適切か ## UIの変更 - なし ## 動作確認状況 - ローカルで確認
This commit is contained in:
parent
41e4fbb8de
commit
cec740f65e
@ -1849,6 +1849,100 @@
|
||||
"security": [{ "bearer": [] }]
|
||||
}
|
||||
},
|
||||
"/files/template/upload-location": {
|
||||
"get": {
|
||||
"operationId": "uploadTemplateLocation",
|
||||
"summary": "",
|
||||
"description": "ログイン中ユーザー用のBlob Storage上のテンプレートファイルのアップロード先アクセスURLを取得します",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "成功時のレスポンス",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/TemplateUploadLocationResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "認証エラー",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": { "$ref": "#/components/schemas/ErrorResponse" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "想定外のサーバーエラー",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": { "$ref": "#/components/schemas/ErrorResponse" }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": ["files"],
|
||||
"security": [{ "bearer": [] }]
|
||||
}
|
||||
},
|
||||
"/files/template/upload-finished": {
|
||||
"post": {
|
||||
"operationId": "uploadTemplateFinished",
|
||||
"summary": "",
|
||||
"description": "アップロードが完了したテンプレートファイルの情報を登録します",
|
||||
"parameters": [],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/TemplateUploadFinishedRequest"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "成功時のレスポンス",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/TemplateUploadFinishedReqponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "不正なパラメータ",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": { "$ref": "#/components/schemas/ErrorResponse" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "認証エラー",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": { "$ref": "#/components/schemas/ErrorResponse" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "想定外のサーバーエラー",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": { "$ref": "#/components/schemas/ErrorResponse" }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": ["files"],
|
||||
"security": [{ "bearer": [] }]
|
||||
}
|
||||
},
|
||||
"/tasks": {
|
||||
"get": {
|
||||
"operationId": "getTasks",
|
||||
@ -2671,6 +2765,44 @@
|
||||
"security": [{ "bearer": [] }]
|
||||
}
|
||||
},
|
||||
"/templates": {
|
||||
"get": {
|
||||
"operationId": "getTemplates",
|
||||
"summary": "",
|
||||
"description": "アカウント内のテンプレートファイルの一覧を取得します",
|
||||
"parameters": [],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "成功時のレスポンス",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/GetTemplatesResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "認証エラー",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": { "$ref": "#/components/schemas/ErrorResponse" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "想定外のサーバーエラー",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": { "$ref": "#/components/schemas/ErrorResponse" }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": ["templates"],
|
||||
"security": [{ "bearer": [] }]
|
||||
}
|
||||
},
|
||||
"/notification/register": {
|
||||
"post": {
|
||||
"operationId": "register",
|
||||
@ -3602,6 +3734,36 @@
|
||||
"properties": { "url": { "type": "string" } },
|
||||
"required": ["url"]
|
||||
},
|
||||
"TemplateUploadLocationResponse": {
|
||||
"type": "object",
|
||||
"properties": { "url": { "type": "string" } },
|
||||
"required": ["url"]
|
||||
},
|
||||
"TemplateFile": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "テンプレートファイルのファイル名"
|
||||
},
|
||||
"url": {
|
||||
"type": "string",
|
||||
"description": "テンプレートファイルのURL"
|
||||
}
|
||||
},
|
||||
"required": ["name", "url"]
|
||||
},
|
||||
"TemplateUploadFinishedRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"templateFile": {
|
||||
"description": "テンプレートファイルのファイル情報",
|
||||
"allOf": [{ "$ref": "#/components/schemas/TemplateFile" }]
|
||||
}
|
||||
},
|
||||
"required": ["templateFile"]
|
||||
},
|
||||
"TemplateUploadFinishedReqponse": { "type": "object", "properties": {} },
|
||||
"Assignee": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -3808,6 +3970,17 @@
|
||||
"required": ["poNumber"]
|
||||
},
|
||||
"CancelOrderResponse": { "type": "object", "properties": {} },
|
||||
"GetTemplatesResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"templates": {
|
||||
"description": "テンプレートファイルの一覧",
|
||||
"type": "array",
|
||||
"items": { "$ref": "#/components/schemas/TemplateFile" }
|
||||
}
|
||||
},
|
||||
"required": ["templates"]
|
||||
},
|
||||
"RegisterRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@ -28,6 +28,8 @@ import { NotificationModule } from './features/notification/notification.module'
|
||||
import { FilesModule } from './features/files/files.module';
|
||||
import { FilesController } from './features/files/files.controller';
|
||||
import { FilesService } from './features/files/files.service';
|
||||
import { TemplatesModule } from './features/templates/templates.module';
|
||||
import { TemplatesController } from './features/templates/templates.controller';
|
||||
import { TasksService } from './features/tasks/tasks.service';
|
||||
import { TasksController } from './features/tasks/tasks.controller';
|
||||
import { TasksModule } from './features/tasks/tasks.module';
|
||||
@ -41,6 +43,7 @@ import { UserGroupsRepositoryModule } from './repositories/user_groups/user_grou
|
||||
import { SortCriteriaRepositoryModule } from './repositories/sort_criteria/sort_criteria.repository.module';
|
||||
import { TemplateFilesRepositoryModule } from './repositories/template_files/template_files.repository.module';
|
||||
import { WorktypesRepositoryModule } from './repositories/worktypes/worktypes.repository.module';
|
||||
import { TemplatesService } from './features/templates/templates.service';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@ -65,6 +68,7 @@ import { WorktypesRepositoryModule } from './repositories/worktypes/worktypes.re
|
||||
FilesModule,
|
||||
TasksModule,
|
||||
UsersModule,
|
||||
TemplatesModule,
|
||||
SendGridModule,
|
||||
LicensesModule,
|
||||
AccountsRepositoryModule,
|
||||
@ -106,6 +110,7 @@ import { WorktypesRepositoryModule } from './repositories/worktypes/worktypes.re
|
||||
TasksController,
|
||||
UsersController,
|
||||
LicensesController,
|
||||
TemplatesController,
|
||||
],
|
||||
providers: [
|
||||
AuthService,
|
||||
@ -115,6 +120,7 @@ import { WorktypesRepositoryModule } from './repositories/worktypes/worktypes.re
|
||||
FilesService,
|
||||
TasksService,
|
||||
LicensesService,
|
||||
TemplatesService,
|
||||
],
|
||||
})
|
||||
export class AppModule {
|
||||
|
||||
@ -27,10 +27,13 @@ import {
|
||||
AudioUploadLocationResponse,
|
||||
TemplateDownloadLocationRequest,
|
||||
TemplateDownloadLocationResponse,
|
||||
TemplateUploadFinishedReqponse,
|
||||
TemplateUploadFinishedRequest,
|
||||
TemplateUploadLocationResponse,
|
||||
} from './types/types';
|
||||
import { AuthGuard } from '../../common/guards/auth/authguards';
|
||||
import { RoleGuard } from '../../common/guards/role/roleguards';
|
||||
import { USER_ROLES } from '../../constants';
|
||||
import { ADMIN_ROLES, USER_ROLES } from '../../constants';
|
||||
import { retrieveAuthorizationToken } from '../../common/http/helper';
|
||||
import { Request } from 'express';
|
||||
import { makeContext } from '../../common/log';
|
||||
@ -258,4 +261,84 @@ export class FilesController {
|
||||
|
||||
return { url };
|
||||
}
|
||||
|
||||
@Get('template/upload-location')
|
||||
@ApiResponse({
|
||||
status: HttpStatus.OK,
|
||||
type: TemplateUploadLocationResponse,
|
||||
description: '成功時のレスポンス',
|
||||
})
|
||||
@ApiResponse({
|
||||
status: HttpStatus.UNAUTHORIZED,
|
||||
description: '認証エラー',
|
||||
type: ErrorResponse,
|
||||
})
|
||||
@ApiResponse({
|
||||
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
description: '想定外のサーバーエラー',
|
||||
type: ErrorResponse,
|
||||
})
|
||||
@ApiOperation({
|
||||
operationId: 'uploadTemplateLocation',
|
||||
description:
|
||||
'ログイン中ユーザー用のBlob Storage上のテンプレートファイルのアップロード先アクセスURLを取得します',
|
||||
})
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(AuthGuard)
|
||||
@UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] }))
|
||||
async uploadTemplateLocation(
|
||||
@Req() req: Request,
|
||||
): Promise<TemplateUploadLocationResponse> {
|
||||
const token = retrieveAuthorizationToken(req);
|
||||
const accessToken = jwt.decode(token, { json: true }) as AccessToken;
|
||||
|
||||
const context = makeContext(accessToken.userId);
|
||||
|
||||
console.log(context.trackingId);
|
||||
|
||||
return { url: '' };
|
||||
}
|
||||
|
||||
@ApiResponse({
|
||||
status: HttpStatus.OK,
|
||||
type: TemplateUploadFinishedReqponse,
|
||||
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: 'uploadTemplateFinished',
|
||||
description: 'アップロードが完了したテンプレートファイルの情報を登録します',
|
||||
})
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(AuthGuard)
|
||||
@UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] }))
|
||||
@Post('template/upload-finished')
|
||||
async templateUploadFinished(
|
||||
@Req() req: Request,
|
||||
@Body() body: TemplateUploadFinishedRequest,
|
||||
): Promise<TemplateUploadFinishedReqponse> {
|
||||
const { templateFile } = body;
|
||||
const token = retrieveAuthorizationToken(req);
|
||||
const accessToken = jwt.decode(token, { json: true }) as AccessToken;
|
||||
|
||||
const context = makeContext(accessToken.userId);
|
||||
console.log(context.trackingId);
|
||||
console.log(templateFile);
|
||||
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { TemplateFile } from '../../templates/types/types';
|
||||
|
||||
export class AudioUploadLocationRequest {}
|
||||
|
||||
@ -31,6 +32,11 @@ export class TemplateDownloadLocationResponse {
|
||||
url: string;
|
||||
}
|
||||
|
||||
export class TemplateUploadLocationResponse {
|
||||
@ApiProperty()
|
||||
url: string;
|
||||
}
|
||||
|
||||
export class AudioOptionItem {
|
||||
@ApiProperty({ minLength: 1, maxLength: 16 })
|
||||
optionItemLabel: string;
|
||||
@ -87,3 +93,10 @@ export class AudioUploadFinishedResponse {
|
||||
@ApiProperty({ description: '8桁固定の数字' })
|
||||
jobNumber: string;
|
||||
}
|
||||
|
||||
export class TemplateUploadFinishedRequest {
|
||||
@ApiProperty({ description: 'テンプレートファイルのファイル情報' })
|
||||
templateFile: TemplateFile;
|
||||
}
|
||||
|
||||
export class TemplateUploadFinishedReqponse {}
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { ConfigModule } from '@nestjs/config';
|
||||
import { TemplatesController } from './templates.controller';
|
||||
import { TemplatesService } from './templates.service';
|
||||
|
||||
describe('TemplatesController', () => {
|
||||
let controller: TemplatesController;
|
||||
const mockTemplatesService = {};
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
imports: [
|
||||
ConfigModule.forRoot({
|
||||
envFilePath: ['.env.local', '.env'],
|
||||
isGlobal: true,
|
||||
}),
|
||||
],
|
||||
controllers: [TemplatesController],
|
||||
providers: [TemplatesService],
|
||||
})
|
||||
.overrideProvider(TemplatesService)
|
||||
.useValue(mockTemplatesService)
|
||||
.compile();
|
||||
|
||||
controller = module.get<TemplatesController>(TemplatesController);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(controller).toBeDefined();
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,57 @@
|
||||
import { Controller, Get, HttpStatus, 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 { GetTemplatesResponse } from './types/types';
|
||||
import { AuthGuard } from '../../common/guards/auth/authguards';
|
||||
import { RoleGuard } from '../../common/guards/role/roleguards';
|
||||
import { ADMIN_ROLES } from '../../constants';
|
||||
import { retrieveAuthorizationToken } from '../../common/http/helper';
|
||||
import { Request } from 'express';
|
||||
import { makeContext } from '../../common/log';
|
||||
import { TemplatesService } from './templates.service';
|
||||
|
||||
@ApiTags('templates')
|
||||
@Controller('templates')
|
||||
export class TemplatesController {
|
||||
constructor(private readonly templatesService: TemplatesService) {}
|
||||
|
||||
@ApiResponse({
|
||||
status: HttpStatus.OK,
|
||||
type: GetTemplatesResponse,
|
||||
description: '成功時のレスポンス',
|
||||
})
|
||||
@ApiResponse({
|
||||
status: HttpStatus.UNAUTHORIZED,
|
||||
description: '認証エラー',
|
||||
type: ErrorResponse,
|
||||
})
|
||||
@ApiResponse({
|
||||
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
||||
description: '想定外のサーバーエラー',
|
||||
type: ErrorResponse,
|
||||
})
|
||||
@ApiOperation({
|
||||
operationId: 'getTemplates',
|
||||
description: 'アカウント内のテンプレートファイルの一覧を取得します',
|
||||
})
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(AuthGuard)
|
||||
@UseGuards(RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN] }))
|
||||
@Get()
|
||||
async getTemplates(@Req() req: Request): Promise<GetTemplatesResponse> {
|
||||
const token = retrieveAuthorizationToken(req);
|
||||
const accessToken = jwt.decode(token, { json: true }) as AccessToken;
|
||||
|
||||
const context = makeContext(accessToken.userId);
|
||||
console.log(context.trackingId);
|
||||
|
||||
return { templates: [] };
|
||||
}
|
||||
}
|
||||
10
dictation_server/src/features/templates/templates.module.ts
Normal file
10
dictation_server/src/features/templates/templates.module.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TemplatesController } from './templates.controller';
|
||||
import { TemplatesService } from './templates.service';
|
||||
|
||||
@Module({
|
||||
imports: [],
|
||||
providers: [TemplatesService],
|
||||
controllers: [TemplatesController],
|
||||
})
|
||||
export class TemplatesModule {}
|
||||
@ -0,0 +1,7 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
@Injectable()
|
||||
export class TemplatesService {
|
||||
private readonly logger = new Logger(TemplatesService.name);
|
||||
constructor() {}
|
||||
}
|
||||
16
dictation_server/src/features/templates/types/types.ts
Normal file
16
dictation_server/src/features/templates/types/types.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class TemplateFile {
|
||||
@ApiProperty({ description: 'テンプレートファイルのファイル名' })
|
||||
name: string;
|
||||
@ApiProperty({ description: 'テンプレートファイルのURL' })
|
||||
url: string;
|
||||
}
|
||||
|
||||
export class GetTemplatesResponse {
|
||||
@ApiProperty({
|
||||
description: 'テンプレートファイルの一覧',
|
||||
type: [TemplateFile],
|
||||
})
|
||||
templates: TemplateFile[];
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user