Merged PR 445: DBマイグレーション(削除ユーザの情報退避テーブル)

## 概要
[Task2682: DBマイグレーション(削除ユーザの情報退避テーブル)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2682)

削除ユーザー退避テーブルを作成しました。
license_allocation_historyテーブルにaccountIdのカラムを追加しました。
また、ライセンス割り当て・割り当て解除時にlicense_allocation_historyテーブルにaccountIdを登録するようにしました。

## レビューポイント
なし

## UIの変更
なし

## 動作確認状況
ローカルでUT、動作確認実施済み

## 補足
削除ユーザー退避テーブルは現在のユーザーテーブルをほぼそのままの形で作成しています。
(idのAUTO_INCREMENTだけ外しています)
This commit is contained in:
oura.a 2023-09-28 08:16:20 +00:00
parent ded673ec74
commit 423e5ab1e3
7 changed files with 133 additions and 12 deletions

View File

@ -0,0 +1,5 @@
-- +migrate Up
ALTER TABLE `license_allocation_history` ADD COLUMN `account_id` BIGINT UNSIGNED NOT NULL COMMENT 'アカウントID' AFTER `is_allocated`;
-- +migrate Down
ALTER TABLE `license_allocation_history` DROP COLUMN `account_id`;

View File

@ -0,0 +1,23 @@
-- +migrate Up
CREATE TABLE IF NOT EXISTS `users_archive` (
`id` BIGINT UNSIGNED NOT NULL PRIMARY KEY COMMENT 'ID',
`external_id` VARCHAR(255) NOT NULL COMMENT '外部ユーザーID',
`account_id` BIGINT UNSIGNED COMMENT 'アカウントID',
`role` VARCHAR(255) NOT NULL COMMENT '役職',
`author_id` VARCHAR(255) COMMENT 'AuthorID',
`accepted_terms_version` VARCHAR(255) NOT NULL COMMENT '同意済み利用規約バージョン',
`email_verified` BOOLEAN NOT NULL DEFAULT 0 COMMENT 'email認証が完了済みであるか',
`encryption` BOOLEAN DEFAULT FALSE NOT NULL COMMENT '音声ファイル暗号化するか',
`prompt` BOOLEAN DEFAULT FALSE NOT NULL COMMENT '録音時に強制的にWorkTypeIDの選択画面に遷移するか',
`deleted_at` TIMESTAMP COMMENT '削除時刻',
`created_by` VARCHAR(255) COMMENT '作成者',
`created_at` TIMESTAMP DEFAULT now() COMMENT '作成時刻',
`updated_by` VARCHAR(255) COMMENT '更新者',
`updated_at` TIMESTAMP DEFAULT now() COMMENT '更新時刻',
`auto_renew` BOOLEAN DEFAULT TRUE NOT NULL COMMENT 'ライセンスの自動更新をするかどうか',
`license_alert` BOOLEAN DEFAULT TRUE NOT NULL COMMENT 'ライセンスの期限切れ通知をするかどうか',
`notification` BOOLEAN DEFAULT TRUE NOT NULL COMMENT '完了通知をするかどうか'
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci;
-- +migrate Down
DROP TABLE `users_archive`;

View File

@ -552,7 +552,14 @@ describe('ライセンス割り当て', () => {
null,
null,
);
await createLicenseAllocationHistory(source, 1, userId, 1, 'NONE');
await createLicenseAllocationHistory(
source,
1,
userId,
1,
accountId,
'NONE',
);
const service = module.get<UsersService>(UsersService);
@ -581,6 +588,9 @@ describe('ライセンス割り当て', () => {
expect(licenseAllocationHistory.licenseAllocationHistory.is_allocated).toBe(
true,
);
expect(licenseAllocationHistory.licenseAllocationHistory.account_id).toBe(
accountId,
);
});
it('再割り当て可能なライセンスに対して、ライセンス割り当てが完了する', async () => {
@ -607,7 +617,14 @@ describe('ライセンス割り当て', () => {
null,
null,
);
await createLicenseAllocationHistory(source, 1, userId, 1, 'NONE');
await createLicenseAllocationHistory(
source,
1,
userId,
1,
accountId,
'NONE',
);
const service = module.get<UsersService>(UsersService);
@ -630,6 +647,9 @@ describe('ライセンス割り当て', () => {
expect(licenseAllocationHistory.licenseAllocationHistory.is_allocated).toBe(
true,
);
expect(licenseAllocationHistory.licenseAllocationHistory.account_id).toBe(
accountId,
);
});
it('未割当のライセンスに対して、別のライセンスが割り当てられているユーザーの割り当てが完了する', async () => {
@ -668,7 +688,14 @@ describe('ライセンス割り当て', () => {
null,
null,
);
await createLicenseAllocationHistory(source, 1, userId, 1, 'NONE');
await createLicenseAllocationHistory(
source,
1,
userId,
1,
accountId,
'NONE',
);
const service = module.get<UsersService>(UsersService);
@ -695,6 +722,9 @@ describe('ライセンス割り当て', () => {
expect(licenseAllocationHistory.licenseAllocationHistory.is_allocated).toBe(
false,
);
expect(licenseAllocationHistory.licenseAllocationHistory.account_id).toBe(
accountId,
);
// 新たに割り当てたライセンスの状態確認
const result2 = await selectLicense(source, 2);
@ -717,6 +747,9 @@ describe('ライセンス割り当て', () => {
expect(
newlicenseAllocationHistory.licenseAllocationHistory.is_allocated,
).toBe(true);
expect(
newlicenseAllocationHistory.licenseAllocationHistory.account_id,
).toBe(accountId);
});
it('割り当て時にライセンス履歴テーブルへの登録が完了する元がNORMALのとき', async () => {
@ -755,7 +788,14 @@ describe('ライセンス割り当て', () => {
null,
null,
);
await createLicenseAllocationHistory(source, 1, userId, 1, 'NONE');
await createLicenseAllocationHistory(
source,
1,
userId,
1,
accountId,
'NONE',
);
const service = module.get<UsersService>(UsersService);
await service.allocateLicense(makeContext('trackingId'), userId, 2);
@ -806,7 +846,14 @@ describe('ライセンス割り当て', () => {
null,
null,
);
await createLicenseAllocationHistory(source, 1, userId, 1, 'CARD');
await createLicenseAllocationHistory(
source,
1,
userId,
1,
accountId,
'CARD',
);
const service = module.get<UsersService>(UsersService);
await service.allocateLicense(makeContext('trackingId'), userId, 2);
@ -857,7 +904,14 @@ describe('ライセンス割り当て', () => {
null,
null,
);
await createLicenseAllocationHistory(source, 1, userId, 1, 'TRIAL');
await createLicenseAllocationHistory(
source,
1,
userId,
1,
accountId,
'TRIAL',
);
const service = module.get<UsersService>(UsersService);
await service.allocateLicense(makeContext('trackingId'), userId, 2);
@ -1000,7 +1054,14 @@ describe('ライセンス割り当て解除', () => {
null,
null,
);
await createLicenseAllocationHistory(source, 1, userId, 1, 'NONE');
await createLicenseAllocationHistory(
source,
1,
userId,
1,
accountId,
'NONE',
);
const service = module.get<UsersService>(UsersService);
await service.deallocateLicense(makeContext('trackingId'), userId);
@ -1028,6 +1089,9 @@ describe('ライセンス割り当て解除', () => {
expect(licenseAllocationHistory.licenseAllocationHistory.is_allocated).toBe(
false,
);
expect(licenseAllocationHistory.licenseAllocationHistory.account_id).toBe(
accountId,
);
expect(
licenseAllocationHistory.licenseAllocationHistory.switch_from_type,
).toBe('NONE');
@ -1075,7 +1139,14 @@ describe('ライセンス割り当て解除', () => {
null,
null,
);
await createLicenseAllocationHistory(source, 1, userId, 1, 'NONE');
await createLicenseAllocationHistory(
source,
1,
userId,
1,
accountId,
'NONE',
);
const service = module.get<UsersService>(UsersService);
await expect(

View File

@ -78,6 +78,7 @@ export const createLicenseAllocationHistory = async (
historyId: number,
userId: number,
licenseId: number,
accountId: number,
type: string,
): Promise<void> => {
const { identifiers } = await datasource
@ -87,6 +88,7 @@ export const createLicenseAllocationHistory = async (
user_id: userId,
license_id: licenseId,
is_allocated: true,
account_id: accountId,
executed_at: new Date(),
switch_from_type: type,
deleted_at: null,

View File

@ -892,7 +892,14 @@ export class UsersService {
);
try {
await this.licensesRepository.allocateLicense(userId, newLicenseId);
const accountId = (await this.usersRepository.findUserById(userId))
.account_id;
await this.licensesRepository.allocateLicense(
userId,
newLicenseId,
accountId,
);
} catch (e) {
this.logger.error(`error=${e}`);
if (e instanceof Error) {
@ -933,7 +940,10 @@ export class UsersService {
);
try {
await this.licensesRepository.deallocateLicense(userId);
const accountId = (await this.usersRepository.findUserById(userId))
.account_id;
await this.licensesRepository.deallocateLicense(userId, accountId);
} catch (e) {
this.logger.error(`error=${e}`);
if (e instanceof Error) {

View File

@ -160,6 +160,9 @@ export class LicenseAllocationHistory {
@Column()
is_allocated: boolean;
@Column()
account_id: number;
@Column()
executed_at: Date;

View File

@ -452,7 +452,11 @@ export class LicensesRepositoryService {
* @param userId
* @param newLicenseId
*/
async allocateLicense(userId: number, newLicenseId: number): Promise<void> {
async allocateLicense(
userId: number,
newLicenseId: number,
accountId: number,
): Promise<void> {
await this.dataSource.transaction(async (entityManager) => {
const licenseRepo = entityManager.getRepository(License);
const licenseAllocationHistoryRepo = entityManager.getRepository(
@ -503,6 +507,7 @@ export class LicensesRepositoryService {
const deallocationHistory = new LicenseAllocationHistory();
deallocationHistory.user_id = userId;
deallocationHistory.license_id = allocatedLicense.id;
deallocationHistory.account_id = accountId;
deallocationHistory.is_allocated = false;
deallocationHistory.executed_at = new Date();
deallocationHistory.switch_from_type = SWITCH_FROM_TYPE.NONE;
@ -548,6 +553,7 @@ export class LicensesRepositoryService {
const allocationHistory = new LicenseAllocationHistory();
allocationHistory.user_id = userId;
allocationHistory.license_id = targetLicense.id;
allocationHistory.account_id = accountId;
allocationHistory.is_allocated = true;
allocationHistory.executed_at = new Date();
// TODO switchFromTypeの値については「PBI1234: 第一階層として、ライセンス数推移情報をCSV出力したい」で正式対応
@ -561,7 +567,7 @@ export class LicensesRepositoryService {
*
* @param userId
*/
async deallocateLicense(userId: number): Promise<void> {
async deallocateLicense(userId: number, accountId: number): Promise<void> {
await this.dataSource.transaction(async (entityManager) => {
const licenseRepo = entityManager.getRepository(License);
const licenseAllocationHistoryRepo = entityManager.getRepository(
@ -591,6 +597,7 @@ export class LicensesRepositoryService {
const deallocationHistory = new LicenseAllocationHistory();
deallocationHistory.user_id = userId;
deallocationHistory.license_id = allocatedLicense.id;
deallocationHistory.account_id = accountId;
deallocationHistory.is_allocated = false;
deallocationHistory.executed_at = new Date();
deallocationHistory.switch_from_type = SWITCH_FROM_TYPE.NONE;