Merged PR 466: [PBI1220残]退避テーブル対応(月の途中で退会したアカウントの集計対応)

## 概要
[Task2767: [PBI1220残]退避テーブル対応(月の途中で退会したアカウントの集計対応)](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2767)

アカウント削除時に以下のテーブルの削除対象データを退避する処理を追加しました。
・ライセンステーブル
・ライセンス割り当て履歴テーブル

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

## UIの変更
なし

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

## 補足
なし
This commit is contained in:
oura.a 2023-10-06 06:04:11 +00:00
parent 1eedc5c0be
commit aef6a35a7d
6 changed files with 204 additions and 2 deletions

View File

@ -1,6 +1,6 @@
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
import { DataSource } from 'typeorm'; import { DataSource } from 'typeorm';
import { User } from '../../repositories/users/entity/user.entity'; import { User, UserArchive } from '../../repositories/users/entity/user.entity';
import { Account } from '../../repositories/accounts/entity/account.entity'; import { Account } from '../../repositories/accounts/entity/account.entity';
import { ADMIN_ROLES, USER_ROLES } from '../../constants'; import { ADMIN_ROLES, USER_ROLES } from '../../constants';
@ -368,3 +368,14 @@ export const getUser = async (
export const getUsers = async (dataSource: DataSource): Promise<User[]> => { export const getUsers = async (dataSource: DataSource): Promise<User[]> => {
return await dataSource.getRepository(User).find(); return await dataSource.getRepository(User).find();
}; };
/**
* ユーティリティ: ユーザー退避テーブルの内容を取得する
* @param dataSource
* @returns 退
*/
export const getUserArchive = async (
dataSource: DataSource,
): Promise<UserArchive[]> => {
return await dataSource.getRepository(UserArchive).find();
};

View File

@ -35,6 +35,7 @@ import {
makeTestUser, makeTestUser,
makeHierarchicalAccounts, makeHierarchicalAccounts,
getUser, getUser,
getUserArchive,
} from '../../common/test/utility'; } from '../../common/test/utility';
import { AccountsService } from './accounts.service'; import { AccountsService } from './accounts.service';
import { Context, makeContext } from '../../common/log'; import { Context, makeContext } from '../../common/log';
@ -59,7 +60,10 @@ import { AdB2cService } from '../../gateways/adb2c/adb2c.service';
import { BlobstorageService } from '../../gateways/blobstorage/blobstorage.service'; import { BlobstorageService } from '../../gateways/blobstorage/blobstorage.service';
import { UserGroupsRepositoryService } from '../../repositories/user_groups/user_groups.repository.service'; import { UserGroupsRepositoryService } from '../../repositories/user_groups/user_groups.repository.service';
import { import {
createLicenseAllocationHistory,
createOrder, createOrder,
getLicenseArchive,
getLicenseAllocationHistoryArchive,
selectLicense, selectLicense,
selectOrderLicense, selectOrderLicense,
} from '../licenses/test/utility'; } from '../licenses/test/utility';
@ -5350,6 +5354,28 @@ describe('deleteAccountAndData', () => {
const user = await makeTestUser(source, { const user = await makeTestUser(source, {
account_id: tier5Accounts.account.id, account_id: tier5Accounts.account.id,
}); });
// ライセンス作成
await createLicense(
source,
1,
new Date(),
tier5Accounts.account.id,
LICENSE_TYPE.NORMAL,
LICENSE_ALLOCATED_STATUS.UNALLOCATED,
null,
user.id,
null,
null,
);
await createLicenseAllocationHistory(
source,
1,
user.id,
1,
tier5Accounts.account.id,
'NONE',
);
// ADB2Cユーザーの削除成功 // ADB2Cユーザーの削除成功
overrideAdB2cService(service, { overrideAdB2cService(service, {
deleteUsers: jest.fn(), deleteUsers: jest.fn(),
@ -5371,6 +5397,16 @@ describe('deleteAccountAndData', () => {
const userRecord = await getUser(source, user.id); const userRecord = await getUser(source, user.id);
expect(userRecord).toBe(null); expect(userRecord).toBe(null);
const UserArchive = await getUserArchive(source);
expect(UserArchive.length).toBe(2);
const LicenseArchive = await getLicenseArchive(source);
expect(LicenseArchive.length).toBe(1);
const LicenseAllocationHistoryArchive =
await getLicenseAllocationHistoryArchive(source);
expect(LicenseAllocationHistoryArchive.length).toBe(1);
}); });
it('アカウントの削除に失敗した場合はエラーを返す', async () => { it('アカウントの削除に失敗した場合はエラーを返す', async () => {
const module = await makeTestingModule(source); const module = await makeTestingModule(source);

View File

@ -5,6 +5,8 @@ import {
CardLicenseIssue, CardLicenseIssue,
LicenseAllocationHistory, LicenseAllocationHistory,
LicenseOrder, LicenseOrder,
LicenseArchive,
LicenseAllocationHistoryArchive,
} from '../../../repositories/licenses/entity/license.entity'; } from '../../../repositories/licenses/entity/license.entity';
export const createLicense = async ( export const createLicense = async (
@ -189,3 +191,25 @@ export const selectOrderLicense = async (
}); });
return { orderLicense }; return { orderLicense };
}; };
/**
* ユーティリティ: ライセンス退避テーブルの内容を取得する
* @param dataSource
* @returns 退
*/
export const getLicenseArchive = async (
dataSource: DataSource,
): Promise<LicenseArchive[]> => {
return await dataSource.getRepository(LicenseArchive).find();
};
/**
* ユーティリティ: ライセンス割り当て履歴退避テーブルの内容を取得する
* @param dataSource
* @returns 退
*/
export const getLicenseAllocationHistoryArchive = async (
dataSource: DataSource,
): Promise<LicenseAllocationHistoryArchive[]> => {
return await dataSource.getRepository(LicenseAllocationHistoryArchive).find();
};

View File

@ -12,7 +12,13 @@ import {
} from 'typeorm'; } from 'typeorm';
import { User, UserArchive } from '../users/entity/user.entity'; import { User, UserArchive } from '../users/entity/user.entity';
import { Account } from './entity/account.entity'; import { Account } from './entity/account.entity';
import { License, LicenseOrder } from '../licenses/entity/license.entity'; import {
License,
LicenseAllocationHistory,
LicenseAllocationHistoryArchive,
LicenseArchive,
LicenseOrder,
} from '../licenses/entity/license.entity';
import { SortCriteria } from '../sort_criteria/entity/sort_criteria.entity'; import { SortCriteria } from '../sort_criteria/entity/sort_criteria.entity';
import { import {
getDirection, getDirection,
@ -923,6 +929,39 @@ export class AccountsRepositoryService {
.into(UserArchive) .into(UserArchive)
.values(users) .values(users)
.execute(); .execute();
// 削除対象のライセンスを退避テーブルに退避
const licenses = await this.dataSource.getRepository(License).find({
where: {
account_id: accountId,
},
});
const licenseArchiveRepo = entityManager.getRepository(LicenseArchive);
await licenseArchiveRepo
.createQueryBuilder()
.insert()
.into(LicenseArchive)
.values(licenses)
.execute();
// 削除対象のライセンス割り当て履歴を退避テーブルに退避
const licenseHistories = await this.dataSource
.getRepository(LicenseAllocationHistory)
.find({
where: {
account_id: accountId,
},
});
const licenseHistoryArchiveRepo = entityManager.getRepository(
LicenseAllocationHistoryArchive,
);
await licenseHistoryArchiveRepo
.createQueryBuilder()
.insert()
.into(LicenseAllocationHistoryArchive)
.values(licenseHistories)
.execute();
// アカウントを削除 // アカウントを削除
// アカウントを削除することで、外部キー制約がで紐づいている関連テーブルのデータも削除される // アカウントを削除することで、外部キー制約がで紐づいている関連テーブルのデータも削除される
const accountRepo = entityManager.getRepository(Account); const accountRepo = entityManager.getRepository(Account);

View File

@ -7,6 +7,7 @@ import {
OneToOne, OneToOne,
JoinColumn, JoinColumn,
ManyToOne, ManyToOne,
PrimaryColumn,
} from 'typeorm'; } from 'typeorm';
import { User } from '../../users/entity/user.entity'; import { User } from '../../users/entity/user.entity';
@ -188,3 +189,90 @@ export class LicenseAllocationHistory {
@JoinColumn({ name: 'license_id' }) @JoinColumn({ name: 'license_id' })
license?: License; license?: License;
} }
@Entity({ name: 'licenses_archive' })
export class LicenseArchive {
@PrimaryColumn()
id: number;
@Column({ nullable: true })
expiry_date: Date;
@Column()
account_id: number;
@Column()
type: string;
@Column()
status: string;
@Column({ nullable: true })
allocated_user_id: number;
@Column({ nullable: true })
order_id: number;
@Column({ nullable: true })
deleted_at: Date;
@Column({ nullable: true })
delete_order_id: number;
@Column({ nullable: true })
created_by: string;
@Column()
created_at: Date;
@Column({ nullable: true })
updated_by: string;
@Column()
updated_at: Date;
@CreateDateColumn()
archived_at: Date;
}
@Entity({ name: 'license_allocation_history_archive' })
export class LicenseAllocationHistoryArchive {
@PrimaryColumn()
id: number;
@Column()
user_id: number;
@Column()
license_id: number;
@Column()
is_allocated: boolean;
@Column()
account_id: number;
@Column()
executed_at: Date;
@Column()
switch_from_type: string;
@Column({ nullable: true })
deleted_at: Date;
@Column({ nullable: true })
created_by: string;
@Column()
created_at: Date;
@Column({ nullable: true })
updated_by: string;
@Column()
updated_at: Date;
@CreateDateColumn()
archived_at: Date;
}

View File

@ -6,6 +6,8 @@ import {
License, License,
LicenseOrder, LicenseOrder,
LicenseAllocationHistory, LicenseAllocationHistory,
LicenseArchive,
LicenseAllocationHistoryArchive,
} from './entity/license.entity'; } from './entity/license.entity';
import { LicensesRepositoryService } from './licenses.repository.service'; import { LicensesRepositoryService } from './licenses.repository.service';
@ -17,6 +19,8 @@ import { LicensesRepositoryService } from './licenses.repository.service';
CardLicense, CardLicense,
CardLicenseIssue, CardLicenseIssue,
LicenseAllocationHistory, LicenseAllocationHistory,
LicenseArchive,
LicenseAllocationHistoryArchive,
]), ]),
], ],
providers: [LicensesRepositoryService], providers: [LicensesRepositoryService],