From bb8e16897dd3d10520fa8d227b317561406286d7 Mon Sep 17 00:00:00 2001 From: "oura.a" Date: Wed, 19 Jul 2023 01:59:13 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20PR=20246:=20API=20IF=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task2210: API IF実装](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2210) パートナーライセンス情報一覧画面のIFを実装しました。 ## レビューポイント なし ## UIの変更 なし ## 動作確認状況 ローカルで確認 ## 補足 なし --- dictation_server/src/api/odms/openapi.json | 107 +++++++++++++++++- .../features/accounts/accounts.controller.ts | 73 +++++++++++- .../src/features/accounts/types/types.ts | 53 ++++++++- 3 files changed, 229 insertions(+), 4 deletions(-) diff --git a/dictation_server/src/api/odms/openapi.json b/dictation_server/src/api/odms/openapi.json index ba26e83..1f5fa4c 100644 --- a/dictation_server/src/api/odms/openapi.json +++ b/dictation_server/src/api/odms/openapi.json @@ -355,6 +355,53 @@ "security": [{ "bearer": [] }] } }, + "/accounts/partner-licenses": { + "post": { + "operationId": "getPartnerLicenses", + "summary": "", + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetPartnerLicensesRequest" + } + } + } + }, + "responses": { + "200": { + "description": "成功時のレスポンス", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GetPartnerLicensesResponse" + } + } + } + }, + "401": { + "description": "認証エラー", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorResponse" } + } + } + }, + "500": { + "description": "想定外のサーバーエラー", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ErrorResponse" } + } + } + } + }, + "tags": ["accounts"], + "security": [{ "bearer": [] }] + } + }, "/users/confirm": { "post": { "operationId": "confirmUser", @@ -1809,11 +1856,67 @@ "maxLength": 2 }, "adminName": { "type": "string" }, - "eMail": { "type": "string" } + "email": { "type": "string" } }, - "required": ["companyName", "country", "adminName", "eMail"] + "required": ["companyName", "country", "adminName", "email"] }, "CreatePartnerAccountResponse": { "type": "object", "properties": {} }, + "GetPartnerLicensesRequest": { + "type": "object", + "properties": { + "limit": { "type": "number" }, + "offset": { "type": "number" }, + "accountId": { "type": "number" } + }, + "required": ["limit", "offset", "accountId"] + }, + "PartnerLicenseInfo": { + "type": "object", + "properties": { + "accountId": { "type": "number", "description": "アカウントID" }, + "tier": { "type": "number", "description": "階層" }, + "companyName": { "type": "string", "description": "アカウント名" }, + "stockLicense": { + "type": "number", + "description": "保有している有効期限が未設定あるいは有効期限内のライセンス数" + }, + "issuedRequested": { + "type": "number", + "description": "子アカウントからの、未発行状態あるいは発行キャンセルされた注文の総ライセンス数" + }, + "shortage": { + "type": "number", + "description": "不足数({Stock license} - {Issue Requested})" + }, + "issueRequesting": { + "type": "number", + "description": "未発行状態あるいは発行キャンセルされた注文の総ライセンス数(=IssueRequestingのStatusの注文の総ライセンス数)" + } + }, + "required": [ + "accountId", + "tier", + "companyName", + "stockLicense", + "issuedRequested", + "shortage", + "issueRequesting" + ] + }, + "GetPartnerLicensesResponse": { + "type": "object", + "properties": { + "total": { "type": "number" }, + "ownPartnerLicense": { + "$ref": "#/components/schemas/PartnerLicenseInfo" + }, + "childrenPartnerLicenses": { + "type": "array", + "items": { "$ref": "#/components/schemas/PartnerLicenseInfo" } + } + }, + "required": ["total", "ownPartnerLicense", "childrenPartnerLicenses"] + }, "ConfirmRequest": { "type": "object", "properties": { "token": { "type": "string" } }, diff --git a/dictation_server/src/features/accounts/accounts.controller.ts b/dictation_server/src/features/accounts/accounts.controller.ts index 503a77e..51455cf 100644 --- a/dictation_server/src/features/accounts/accounts.controller.ts +++ b/dictation_server/src/features/accounts/accounts.controller.ts @@ -26,6 +26,8 @@ import { GetTypistsResponse, CreatePartnerAccountRequest, CreatePartnerAccountResponse, + GetPartnerLicensesRequest, + GetPartnerLicensesResponse, } from './types/types'; import { USER_ROLES, ADMIN_ROLES, TIERS } from '../../constants'; import { AuthGuard } from '../../common/guards/auth/authguards'; @@ -264,7 +266,7 @@ export class AccountsController { @UseGuards( RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN], - tiers: [TIERS.TIER1,TIERS.TIER2,TIERS.TIER3], + tiers: [TIERS.TIER1, TIERS.TIER2, TIERS.TIER3], }), ) async createPartnerAccount( @@ -286,4 +288,73 @@ export class AccountsController { return {}; } + + @Post('partner-licenses') + @ApiResponse({ + status: HttpStatus.OK, + type: GetPartnerLicensesResponse, + description: '成功時のレスポンス', + }) + @ApiResponse({ + status: HttpStatus.UNAUTHORIZED, + description: '認証エラー', + type: ErrorResponse, + }) + @ApiResponse({ + status: HttpStatus.INTERNAL_SERVER_ERROR, + description: '想定外のサーバーエラー', + type: ErrorResponse, + }) + @ApiOperation({ operationId: 'getPartnerLicenses' }) + @ApiBearerAuth() + @UseGuards(AuthGuard) + @UseGuards( + RoleGuard.requireds({ + roles: [ADMIN_ROLES.ADMIN], + tiers: [TIERS.TIER1, TIERS.TIER2, TIERS.TIER3, TIERS.TIER4], + }), + ) + async getPartnerLicenses( + @Req() req: Request, + @Body() body: GetPartnerLicensesRequest, + ): Promise { + const { limit, offset, accountId } = body; + const accessToken = retrieveAuthorizationToken(req); + const payload = jwt.decode(accessToken, { json: true }) as AccessToken; + + // API未実装のうちはサンプルをreturn + const ret: GetPartnerLicensesResponse = { + total: 2, + ownPartnerLicense: { + accountId: 1, + tier: 2, + companyName: 'testAccount', + stockLicense: 30, + issuedRequested: 5, + shortage: 25, + issueRequesting: 100, + }, + childrenPartnerLicenses: [ + { + accountId: 10, + tier: 3, + companyName: 'testChild', + stockLicense: 300, + issuedRequested: 50, + shortage: 250, + issueRequesting: 1000, + }, + { + accountId: 20, + tier: 3, + companyName: 'testChild2', + stockLicense: 700, + issuedRequested: 500, + shortage: 200, + issueRequesting: 51000, + }, + ], + }; + return ret; + } } diff --git a/dictation_server/src/features/accounts/types/types.ts b/dictation_server/src/features/accounts/types/types.ts index f33d0a7..3d12f23 100644 --- a/dictation_server/src/features/accounts/types/types.ts +++ b/dictation_server/src/features/accounts/types/types.ts @@ -134,4 +134,55 @@ export class CreatePartnerAccountRequest { email: string; } -export class CreatePartnerAccountResponse {} \ No newline at end of file +export class CreatePartnerAccountResponse {} + +export class GetPartnerLicensesRequest { + @ApiProperty() + @IsInt() + limit: number; + @ApiProperty() + @IsInt() + offset: number; + @ApiProperty() + accountId: number; +} + +export class PartnerLicenseInfo { + @ApiProperty({ description: 'アカウントID' }) + accountId: number; + + @ApiProperty({ description: '階層' }) + tier: number; + + @ApiProperty({ description: 'アカウント名' }) + companyName: string; + + @ApiProperty({ + description: '保有している有効期限が未設定あるいは有効期限内のライセンス数', + }) + stockLicense: number; + + @ApiProperty({ + description: + '子アカウントからの、未発行状態あるいは発行キャンセルされた注文の総ライセンス数', + }) + issuedRequested: number; + + @ApiProperty({ description: '不足数({Stock license} - {Issue Requested})' }) + shortage: number; + + @ApiProperty({ + description: + '未発行状態あるいは発行キャンセルされた注文の総ライセンス数(=IssueRequestingのStatusの注文の総ライセンス数)', + }) + issueRequesting: number; +} + +export class GetPartnerLicensesResponse { + @ApiProperty() + total: number; + @ApiProperty({ type: PartnerLicenseInfo }) + ownPartnerLicense: PartnerLicenseInfo; + @ApiProperty({ type: [PartnerLicenseInfo] }) + childrenPartnerLicenses: PartnerLicenseInfo[]; +} \ No newline at end of file