## 概要 [Task2361: API実装(割り当て可能ライセンス取得API)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2361) - 元PBI or タスクへのリンク(内容・目的などはそちらにあるはず) - 何をどう変更したか、追加したライブラリなど - このPull Requestでの対象/対象外 - 影響範囲(他の機能にも影響があるか) メモリDB上にライセンスを作成するメソッドの有効期限を指定可能にしたため、 既存テストで特に指定していなかった箇所(デフォルトでnull)はnullを設定。 ## レビューポイント - 特にレビューしてほしい箇所 - 軽微なものや自明なものは記載不要 - 修正範囲が大きい場合などに記載 - 全体的にや仕様を満たしているか等は本当に必要な時のみ記載 取得レコードのソートの関係上、EntityManagerではなく、QueryBuilderでの実装としているが、問題ないか。 ## UIの変更 - Before/Afterのスクショなど - スクショ置き場 ## 動作確認状況 - ローカルで確認 ・正常系 ①メモリDB上に5件の有効なライセンスを作成。無効なライセンスを4件作成。 ※内2件が有効期限null、2件が同一の有効期限、1件が最も遠い有効期限 有効なライセンスのみ取得できることを確認。 serviceの戻り値として、ソートされて取得できることを確認。 (nullが最優先、有効期限の降順、同一の有効期限のものはidで昇順) ②結果が0件(別のアカウントにはライセンスが存在する)の場合(POSTMAN) 正常終了し、空の配列を返却すること。 別のアカウントのライセンスを取得しないこと。 ・異常 ①tier5以外のアカウントで実行(POSTMAN)し、"Token authority failed Error."エラーになることを確認。 ②コンテナを停止して実行(POSTMAN)し、"Internal Server Error."エラーとなることを確認。 ・他 ①ログがポリシに従って出ていることの確認 ## 補足 - 相談、参考資料などがあれば
220 lines
6.1 KiB
TypeScript
220 lines
6.1 KiB
TypeScript
import {
|
|
Body,
|
|
Controller,
|
|
Get,
|
|
HttpStatus,
|
|
Post,
|
|
Req,
|
|
UseGuards,
|
|
} from '@nestjs/common';
|
|
import {
|
|
ApiResponse,
|
|
ApiTags,
|
|
ApiOperation,
|
|
ApiBearerAuth,
|
|
} from '@nestjs/swagger';
|
|
import { ErrorResponse } from '../../common/error/types/types';
|
|
import { LicensesService } from './licenses.service';
|
|
import {
|
|
CreateOrdersResponse,
|
|
CreateOrdersRequest,
|
|
IssueCardLicensesResponse,
|
|
IssueCardLicensesRequest,
|
|
ActivateCardLicensesResponse,
|
|
ActivateCardLicensesRequest,
|
|
GetAllocatableLicensesResponse,
|
|
GetAllocatableLicensesRequest,
|
|
} from './types/types';
|
|
import { Request } from 'express';
|
|
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, TIERS } from '../../constants';
|
|
import jwt from 'jsonwebtoken';
|
|
import { makeContext } from '../../common/log';
|
|
|
|
@ApiTags('licenses')
|
|
@Controller('licenses')
|
|
export class LicensesController {
|
|
constructor(private readonly licensesService: LicensesService) {}
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: CreateOrdersResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.BAD_REQUEST,
|
|
description: '同一PONumberの注文がすでに存在する場合など',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({ operationId: 'createOrders' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({
|
|
roles: [ADMIN_ROLES.ADMIN],
|
|
tiers: [TIERS.TIER2, TIERS.TIER3, TIERS.TIER4, TIERS.TIER5],
|
|
}),
|
|
)
|
|
@Post('/orders')
|
|
async createOrders(
|
|
@Req() req: Request,
|
|
@Body() body: CreateOrdersRequest,
|
|
): Promise<CreateOrdersResponse> {
|
|
console.log(req.header('Authorization'));
|
|
console.log(body);
|
|
|
|
// AuthGuardでチェック済みなのでここでのアクセストークンチェックはしない
|
|
const accessToken = retrieveAuthorizationToken(req);
|
|
const payload = jwt.decode(accessToken, { json: true }) as AccessToken;
|
|
|
|
// ライセンス注文処理
|
|
await this.licensesService.licenseOrders(
|
|
payload,
|
|
body.poNumber,
|
|
body.orderCount,
|
|
);
|
|
return {};
|
|
}
|
|
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: IssueCardLicensesResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({ operationId: 'issueCardLicenses' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN], tiers: [TIERS.TIER1] }),
|
|
)
|
|
@Post('/cards')
|
|
async issueCardLicenses(
|
|
@Req() req: Request,
|
|
@Body() body: IssueCardLicensesRequest,
|
|
): Promise<IssueCardLicensesResponse> {
|
|
console.log(req.header('Authorization'));
|
|
console.log(body);
|
|
|
|
const accessToken = retrieveAuthorizationToken(req);
|
|
const payload = jwt.decode(accessToken, { json: true }) as AccessToken;
|
|
|
|
const cardLicenseKeys = await this.licensesService.issueCardLicenseKeys(
|
|
payload.userId,
|
|
body.createCount,
|
|
);
|
|
|
|
return cardLicenseKeys;
|
|
}
|
|
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: ActivateCardLicensesResponse,
|
|
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: 'activateCardLicenses' })
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN], tiers: [TIERS.TIER5] }),
|
|
)
|
|
@Post('/cards/activate')
|
|
async activateCardLicenses(
|
|
@Req() req: Request,
|
|
@Body() body: ActivateCardLicensesRequest,
|
|
): Promise<ActivateCardLicensesResponse> {
|
|
console.log(req.header('Authorization'));
|
|
console.log(body);
|
|
|
|
const accessToken = retrieveAuthorizationToken(req);
|
|
const payload = jwt.decode(accessToken, { json: true }) as AccessToken;
|
|
|
|
await this.licensesService.activateCardLicenseKey(
|
|
payload.userId,
|
|
body.cardLicenseKey,
|
|
);
|
|
|
|
return {};
|
|
}
|
|
|
|
@ApiResponse({
|
|
status: HttpStatus.OK,
|
|
type: GetAllocatableLicensesResponse,
|
|
description: '成功時のレスポンス',
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.UNAUTHORIZED,
|
|
description: '認証エラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiResponse({
|
|
status: HttpStatus.INTERNAL_SERVER_ERROR,
|
|
description: '想定外のサーバーエラー',
|
|
type: ErrorResponse,
|
|
})
|
|
@ApiOperation({
|
|
operationId: 'getAllocatableLicenses',
|
|
description: '割り当て可能なライセンスを取得します',
|
|
})
|
|
@ApiBearerAuth()
|
|
@UseGuards(AuthGuard)
|
|
@UseGuards(
|
|
RoleGuard.requireds({ roles: [ADMIN_ROLES.ADMIN], tiers: [TIERS.TIER5] }),
|
|
)
|
|
@Get('/allocatable')
|
|
async getAllocatableLicenses(
|
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@Req() req: Request,
|
|
): Promise<GetAllocatableLicensesResponse> {
|
|
const token = retrieveAuthorizationToken(req);
|
|
const payload = jwt.decode(token, { json: true }) as AccessToken;
|
|
|
|
const context = makeContext(payload.userId);
|
|
|
|
const allocatableLicenses =
|
|
await this.licensesService.getAllocatableLicenses(
|
|
context,
|
|
payload.userId,
|
|
);
|
|
|
|
return allocatableLicenses;
|
|
}
|
|
}
|