From 00f4966aa9db3a4af529a0da16c12a855f942f0d Mon Sep 17 00:00:00 2001 From: "maruyama.t" Date: Mon, 16 Oct 2023 09:02:38 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20PR=20470:=20[Sp-19]=E3=82=A2=E3=82=AB?= =?UTF-8?q?=E3=82=A6=E3=83=B3=E3=83=88=E5=89=8A=E9=99=A4=E6=99=82=E3=81=AB?= =?UTF-8?q?=E5=89=8A=E9=99=A4=E3=81=99=E3=82=8B=E3=83=86=E3=83=BC=E3=83=96?= =?UTF-8?q?=E3=83=AB=E3=81=AB=E3=81=A4=E3=81=84=E3=81=A6=E3=80=81on=20dele?= =?UTF-8?q?te=20cascade=E3=81=A7=E3=81=AF=E3=81=AA=E3=81=8F=E3=82=B3?= =?UTF-8?q?=E3=83=BC=E3=83=89=E4=B8=8A=E3=81=A7=E5=89=8A=E9=99=A4=E3=82=92?= =?UTF-8?q?=E8=A1=8C=E3=81=86=E3=82=88=E3=81=86=E4=BF=AE=E6=AD=A3=E3=81=99?= =?UTF-8?q?=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 概要 [Task2783: [Sp-19]アカウント削除時に削除するテーブルについて、on delete cascadeではなくコード上で削除を行うよう修正する](https://paruru.nds-tyo.co.jp:8443/tfs/ReciproCollection/fa4924a4-d079-4fab-9fb5-a9a11eb205f0/_workitems/edit/2783) アカウント削除時に削除するテーブルについて、on delete cascadeではなくコード上で削除を行うよう修正 一部ユニットテスト用にutilityのcreateForeignKeyConstraints: falseに指定 LGTM後、すべてのテーブルのレコード削除の動作確認をDEV環境で実施します。 ## レビューポイント DBマイグレーションファイルが正しく修正されているか ## UIの変更 なし ## 動作確認状況 - ローカルで確認 ## 補足 - 相談、参考資料などがあれば --- ...-delete-foreign-key-for-account-delete.sql | 33 +++ dictation_server/src/common/test/utility.ts | 12 + .../accounts/accounts.service.spec.ts | 211 ++++++++++++++---- .../accounts/accounts.repository.service.ts | 109 ++++++++- .../licenses/entity/license.entity.ts | 8 +- .../repositories/users/entity/user.entity.ts | 4 +- 6 files changed, 327 insertions(+), 50 deletions(-) create mode 100644 dictation_server/db/migrations/045-delete-foreign-key-for-account-delete.sql diff --git a/dictation_server/db/migrations/045-delete-foreign-key-for-account-delete.sql b/dictation_server/db/migrations/045-delete-foreign-key-for-account-delete.sql new file mode 100644 index 0000000..ccb3995 --- /dev/null +++ b/dictation_server/db/migrations/045-delete-foreign-key-for-account-delete.sql @@ -0,0 +1,33 @@ +-- +migrate Up +ALTER TABLE `checkout_permission` DROP FOREIGN KEY `checkout_permission_fk_task_id`; +ALTER TABLE `tasks` DROP FOREIGN KEY `tasks_fk_account_id`; +ALTER TABLE `template_files` DROP FOREIGN KEY `template_files_fk_account_id`; +ALTER TABLE `option_items` DROP FOREIGN KEY `option_items_fk_worktype_id`; +ALTER TABLE `worktypes` DROP FOREIGN KEY `worktypes_fk_account_id`; +ALTER TABLE `audio_option_items` DROP FOREIGN KEY `audio_option_items_fk_audio_file_id`; +ALTER TABLE `audio_files` DROP FOREIGN KEY `audio_files_fk_account_id`; +ALTER TABLE `user_group_member` DROP FOREIGN KEY `user_group_member_fk_user_group_id`; +ALTER TABLE `user_group` DROP FOREIGN KEY `user_group_fk_account_id`; +ALTER TABLE `license_allocation_history` DROP FOREIGN KEY `license_allocation_history_fk_account_id`; +ALTER TABLE `card_licenses` DROP FOREIGN KEY `card_licenses_fk_license_id`; +ALTER TABLE `licenses` DROP FOREIGN KEY `licenses_fk_account_id`; +ALTER TABLE `license_orders` DROP FOREIGN KEY `license_orders_fk_from_account_id`; +ALTER TABLE `sort_criteria` DROP FOREIGN KEY `sort_criteria_fk_user_id`; +ALTER TABLE `users` DROP FOREIGN KEY `users_fk_account_id`; + +-- +migrate Down +ALTER TABLE `checkout_permission` ADD CONSTRAINT `checkout_permission_fk_task_id` FOREIGN KEY (`task_id`) REFERENCES `tasks` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `tasks` ADD CONSTRAINT `tasks_fk_account_id` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `template_files` ADD CONSTRAINT `template_files_fk_account_id` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `option_items` ADD CONSTRAINT `option_items_fk_worktype_id` FOREIGN KEY (`worktype_id`) REFERENCES `worktypes` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `worktypes` ADD CONSTRAINT `worktypes_fk_account_id` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `audio_option_items` ADD CONSTRAINT `audio_option_items_fk_audio_file_id` FOREIGN KEY (`audio_file_id`) REFERENCES `audio_files` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `audio_files` ADD CONSTRAINT `audio_files_fk_account_id` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `user_group_member` ADD CONSTRAINT `user_group_member_fk_user_group_id` FOREIGN KEY (`user_group_id`) REFERENCES `user_group` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `user_group` ADD CONSTRAINT `user_group_fk_account_id` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `license_allocation_history` ADD CONSTRAINT `license_allocation_history_fk_account_id` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `card_licenses` ADD CONSTRAINT `card_licenses_fk_license_id` FOREIGN KEY (`license_id`) REFERENCES `licenses` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `licenses` ADD CONSTRAINT `licenses_fk_account_id` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `license_orders` ADD CONSTRAINT `license_orders_fk_from_account_id` FOREIGN KEY (`from_account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `sort_criteria` ADD CONSTRAINT `sort_criteria_fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE `users` ADD CONSTRAINT `users_fk_account_id` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; \ No newline at end of file diff --git a/dictation_server/src/common/test/utility.ts b/dictation_server/src/common/test/utility.ts index 4722e9f..c56ce8e 100644 --- a/dictation_server/src/common/test/utility.ts +++ b/dictation_server/src/common/test/utility.ts @@ -3,6 +3,7 @@ import { DataSource } from 'typeorm'; import { User, UserArchive } from '../../repositories/users/entity/user.entity'; import { Account } from '../../repositories/accounts/entity/account.entity'; import { ADMIN_ROLES, USER_ROLES } from '../../constants'; +import { License } from '../../repositories/licenses/entity/license.entity'; type InitialTestDBState = { tier1Accounts: { account: Account; users: User[] }[]; @@ -381,3 +382,14 @@ export const getUserArchive = async ( ): Promise => { return await dataSource.getRepository(UserArchive).find(); }; +export const getLicenses = async ( + datasource: DataSource, + account_id: number, +): Promise => { + const licenses = await datasource.getRepository(License).find({ + where: { + account_id: account_id, + }, + }); + return licenses; +}; diff --git a/dictation_server/src/features/accounts/accounts.service.spec.ts b/dictation_server/src/features/accounts/accounts.service.spec.ts index e5ec12d..53c2dd4 100644 --- a/dictation_server/src/features/accounts/accounts.service.spec.ts +++ b/dictation_server/src/features/accounts/accounts.service.spec.ts @@ -35,6 +35,7 @@ import { makeTestUser, makeHierarchicalAccounts, getUser, + getLicenses, getUserArchive, } from '../../common/test/utility'; import { AccountsService } from './accounts.service'; @@ -49,7 +50,11 @@ import { USER_ROLES, WORKTYPE_MAX_COUNT, } from '../../constants'; -import { License } from '../../repositories/licenses/entity/license.entity'; +import { + License, + LicenseAllocationHistory, + LicenseOrder, +} from '../../repositories/licenses/entity/license.entity'; import { overrideAccountsRepositoryService, overrideAdB2cService, @@ -60,7 +65,6 @@ import { AdB2cService } from '../../gateways/adb2c/adb2c.service'; import { BlobstorageService } from '../../gateways/blobstorage/blobstorage.service'; import { UserGroupsRepositoryService } from '../../repositories/user_groups/user_groups.repository.service'; import { - createLicenseAllocationHistory, createOrder, getLicenseArchive, getLicenseAllocationHistoryArchive, @@ -72,7 +76,7 @@ import { AdB2cUser } from '../../gateways/adb2c/types/types'; import { Worktype } from '../../repositories/worktypes/entity/worktype.entity'; import { AccountsRepositoryService } from '../../repositories/accounts/accounts.repository.service'; import { UsersRepositoryService } from '../../repositories/users/users.repository.service'; - +import { UsersService } from '../users/users.service'; describe('createAccount', () => { let source: DataSource = null; beforeEach(async () => { @@ -90,7 +94,6 @@ describe('createAccount', () => { await source.destroy(); source = null; }); - it('アカウントを作成できる', async () => { const module = await makeTestingModule(source); const service = module.get(AccountsService); @@ -5073,8 +5076,9 @@ describe('アカウント情報更新', () => { it('アカウント情報を更新する(ディーラーアカウントが未入力)', async () => { const module = await makeTestingModule(source); const service = module.get(AccountsService); - const { tier3Accounts: tier3Accounts, tier4Accounts: tier4Accounts } = - await makeHierarchicalAccounts(source); + const { tier4Accounts: tier4Accounts } = await makeHierarchicalAccounts( + source, + ); const adduser = await makeTestUser(source, { account_id: tier4Accounts[0].account.id, external_id: 'typist-user-external-id', @@ -5355,45 +5359,117 @@ describe('deleteAccountAndData', () => { it('アカウント情報が削除されること', async () => { const module = await makeTestingModule(source); const service = module.get(AccountsService); - // 第五階層のアカウント作成 - const tier4Accounts = await makeHierarchicalAccounts(source); - const { account: account1, admin: admin1 } = await makeTestAccount(source, { - parent_account_id: tier4Accounts.tier4Accounts[0].account.id, - }); - const account = account1; - const admin = admin1; - const context = makeContext(admin.external_id); - // 第五階層のアカウント作成 - const tier5Accounts = await makeTestAccount(source, { - parent_account_id: account.id, + // 第一~第四階層のアカウント作成 + const { + tier1Accounts: tier1Accounts, + tier2Accounts: tier2Accounts, + tier3Accounts: tier3Accounts, + tier4Accounts: tier4Accounts, + } = await makeHierarchicalAccounts(source); + + // 第五階層のアカウント作成(A) + const tier5AccountsA = await makeTestAccount(source, { + parent_account_id: tier4Accounts[0].account.id, tier: 5, }); - - // ユーザの作成 - const user = await makeTestUser(source, { - account_id: tier5Accounts.account.id, + // 第五階層のアカウント作成(B) + const tier5AccountsB = await makeTestAccount(source, { + parent_account_id: tier4Accounts[0].account.id, + tier: 5, }); - // ライセンス作成 - await createLicense( + // ユーザの作成(A) + const userA = await makeTestUser(source, { + account_id: tier5AccountsA.account.id, + }); + // ユーザの作成(B) + const userB = await makeTestUser(source, { + account_id: tier5AccountsB.account.id, + }); + + const context = makeContext(tier5AccountsA.admin.external_id); + // 第一階層~第五階層までのライセンス注文を作成 + await createLicenseOrder( source, - 1, - new Date(), - tier5Accounts.account.id, - LICENSE_TYPE.NORMAL, - LICENSE_ALLOCATED_STATUS.UNALLOCATED, - null, - user.id, - null, - null, + tier2Accounts[0].account.id, + tier1Accounts[0].account.id, + 100, + 'PO001', ); - await createLicenseAllocationHistory( + await createLicenseOrder( source, - 1, - user.id, - 1, - tier5Accounts.account.id, - 'NONE', + tier3Accounts[0].account.id, + tier2Accounts[0].account.id, + 90, + 'PO002', ); + await createLicenseOrder( + source, + tier4Accounts[0].account.id, + tier3Accounts[0].account.id, + 80, + 'PO003', + ); + await createLicenseOrder( + source, + tier5AccountsA.account.id, + tier4Accounts[0].account.id, + 40, + 'PO004A', + ); + await createLicenseOrder( + source, + tier5AccountsB.account.id, + tier4Accounts[0].account.id, + 40, + 'PO004B', + ); + + // 第一階層~第五階層までのライセンス注文を発行済みにする + await service.issueLicense( + context, + tier2Accounts[0].account.id, + tier1Accounts[0].users[0].external_id, + 1, + 'PO001', + ); + await service.issueLicense( + context, + tier3Accounts[0].account.id, + tier2Accounts[0].users[0].external_id, + 2, + 'PO002', + ); + await service.issueLicense( + context, + tier4Accounts[0].account.id, + tier3Accounts[0].users[0].external_id, + 3, + 'PO003', + ); + await service.issueLicense( + context, + tier5AccountsA.account.id, + tier4Accounts[0].users[0].external_id, + 4, + 'PO004A', + ); + await service.issueLicense( + context, + tier5AccountsB.account.id, + tier4Accounts[0].users[0].external_id, + 4, + 'PO004B', + ); + // アカウントAのライセンスを取得する + const licensesA = await getLicenses(source, tier5AccountsA.account.id); + // アカウントAのライセンスを取得する + const licensesB = await getLicenses(source, tier5AccountsB.account.id); + + const usersService = module.get(UsersService); + // アカウントAのライセンスを割り当てる + await usersService.allocateLicense(context, userA.id, licensesA[0].id); + // アカウントBのライセンスを割り当てる + await usersService.allocateLicense(context, userB.id, licensesB[0].id); // ADB2Cユーザーの削除成功 overrideAdB2cService(service, { @@ -5403,25 +5479,68 @@ describe('deleteAccountAndData', () => { overrideBlobstorageService(service, { deleteContainer: jest.fn(), }); + // アカウント情報の削除 await service.deleteAccountAndData( context, - tier5Accounts.admin.external_id, - tier5Accounts.account.id, + tier5AccountsA.admin.external_id, + tier5AccountsA.account.id, ); - // DB内が想定通りになっているか確認 - const accountRecord = await getAccount(source, tier5Accounts.account.id); - expect(accountRecord).toBe(null); + // 第五階層のアカウントAが削除されていること + const accountRecordA = await getAccount(source, tier5AccountsA.account.id); + expect(accountRecordA).toBe(null); + const userRecordA = await getUser(source, userA.id); + expect(userRecordA).toBe(null); - const userRecord = await getUser(source, user.id); - expect(userRecord).toBe(null); + // 第五階層のアカウントAのライセンスが削除されていること + const licenseRecordA = await source.manager.find(License, { + where: { account_id: tier5AccountsA.account.id }, + }); + expect(licenseRecordA.length).toBe(0); + // 第五階層のアカウントAのライセンス注文履歴が削除されていること + const licenseOrderRecordA = await source.manager.find(LicenseOrder, { + where: { from_account_id: tier5AccountsA.account.id }, + }); + expect(licenseOrderRecordA.length).toBe(0); + // 第五階層のアカウントAのライセンス割り当て履歴が削除されていること + const LicenseAllocationHistoryRecordA = await source.manager.find( + LicenseAllocationHistory, + { + where: { account_id: tier5AccountsA.account.id }, + }, + ); + expect(LicenseAllocationHistoryRecordA.length).toBe(0); + + // 第五階層のアカウントBは削除されていないこと + const accountRecordB = await getAccount(source, tier5AccountsB.account.id); + expect(accountRecordB.id).not.toBeNull(); + const userRecordB = await getUser(source, userB.id); + expect(userRecordB).not.toBeNull(); + // 第五階層のアカウントBのライセンスが削除されていないこと + const licenseRecordB = await source.manager.find(License, { + where: { account_id: tier5AccountsB.account.id }, + }); + expect(licenseRecordB.length).not.toBe(0); + // 第五階層のアカウントBのライセンス注文履歴が削除されていないこと + const licenseOrderRecordB = await source.manager.find(LicenseOrder, { + where: { from_account_id: tier5AccountsB.account.id }, + }); + expect(licenseOrderRecordB.length).not.toBe(0); + // 第五階層のアカウントBのライセンス割り当て履歴が削除されていないこと + const LicenseAllocationHistoryRecordB = await source.manager.find( + LicenseAllocationHistory, + { + where: { account_id: tier5AccountsB.account.id }, + }, + ); + expect(LicenseAllocationHistoryRecordB.length).not.toBe(0); const UserArchive = await getUserArchive(source); expect(UserArchive.length).toBe(2); const LicenseArchive = await getLicenseArchive(source); - expect(LicenseArchive.length).toBe(1); + expect(LicenseArchive.length).toBe(40); const LicenseAllocationHistoryArchive = await getLicenseAllocationHistoryArchive(source); diff --git a/dictation_server/src/repositories/accounts/accounts.repository.service.ts b/dictation_server/src/repositories/accounts/accounts.repository.service.ts index 39fe067..dcf2d7f 100644 --- a/dictation_server/src/repositories/accounts/accounts.repository.service.ts +++ b/dictation_server/src/repositories/accounts/accounts.repository.service.ts @@ -13,6 +13,7 @@ import { import { User, UserArchive } from '../users/entity/user.entity'; import { Account } from './entity/account.entity'; import { + CardLicense, License, LicenseAllocationHistory, LicenseAllocationHistoryArchive, @@ -48,6 +49,14 @@ import { import { DateWithZeroTime } from '../../features/licenses/types/types'; import { Worktype } from '../worktypes/entity/worktype.entity'; import { WorktypeIdNotFoundError } from '../worktypes/errors/types'; +import { OptionItem } from '../worktypes/entity/option_item.entity'; +import { Task } from '../tasks/entity/task.entity'; +import { CheckoutPermission } from '../checkout_permissions/entity/checkout_permission.entity'; +import { AudioFile } from '../audio_files/entity/audio_file.entity'; +import { AudioOptionItem } from '../audio_option_items/entity/audio_option_item.entity'; +import { UserGroup } from '../user_groups/entity/user_group.entity'; +import { UserGroupMember } from '../user_groups/entity/user_group_member.entity'; +import { TemplateFile } from '../template_files/entity/template_file.entity'; @Injectable() export class AccountsRepositoryService { @@ -966,9 +975,107 @@ export class AccountsRepositoryService { .execute(); // アカウントを削除 - // アカウントを削除することで、外部キー制約がで紐づいている関連テーブルのデータも削除される const accountRepo = entityManager.getRepository(Account); await accountRepo.delete({ id: accountId }); + + // ライセンス系(card_license_issue以外)のテーブルのレコードを削除する + const orderRepo = entityManager.getRepository(LicenseOrder); + await orderRepo.delete({ + from_account_id: accountId, + }); + const licenseRepo = entityManager.getRepository(License); + const targetLicenses = await licenseRepo.find({ + where: { + account_id: accountId, + }, + }); + const cardLicenseRepo = entityManager.getRepository(CardLicense); + await cardLicenseRepo.delete({ + license_id: In(targetLicenses.map((license) => license.id)), + }); + await licenseRepo.delete({ + account_id: accountId, + }); + const LicenseAllocationHistoryRepo = entityManager.getRepository( + LicenseAllocationHistory, + ); + await LicenseAllocationHistoryRepo.delete({ + account_id: accountId, + }); + + // ワークタイプ系のテーブルのレコードを削除する + const worktypeRepo = entityManager.getRepository(Worktype); + const taggerWorktypes = await worktypeRepo.find({ + where: { account_id: accountId }, + }); + + const optionItemRepo = entityManager.getRepository(OptionItem); + await optionItemRepo.delete({ + worktype_id: In(taggerWorktypes.map((worktype) => worktype.id)), + }); + await worktypeRepo.delete({ account_id: accountId }); + + // タスク系のテーブルのレコードを削除する + const taskRepo = entityManager.getRepository(Task); + const targetTasks = await taskRepo.find({ + where: { + account_id: accountId, + }, + }); + const checkoutPermissionRepo = + entityManager.getRepository(CheckoutPermission); + await checkoutPermissionRepo.delete({ + task_id: In(targetTasks.map((task) => task.id)), + }); + await taskRepo.delete({ + account_id: accountId, + }); + + // オーディオファイル系のテーブルのレコードを削除する + const audioFileRepo = entityManager.getRepository(AudioFile); + const targetaudioFiles = await audioFileRepo.find({ + where: { + account_id: accountId, + }, + }); + const audioOptionItemsRepo = entityManager.getRepository(AudioOptionItem); + await audioOptionItemsRepo.delete({ + audio_file_id: In(targetaudioFiles.map((audioFile) => audioFile.id)), + }); + await audioFileRepo.delete({ + account_id: accountId, + }); + + // ユーザーグループ系のテーブルのレコードを削除する + const userGroupRepo = entityManager.getRepository(UserGroup); + const targetUserGroup = await userGroupRepo.find({ + where: { + account_id: accountId, + }, + }); + const userGroupMemberRepo = entityManager.getRepository(UserGroupMember); + await userGroupMemberRepo.delete({ + user_group_id: In(targetUserGroup.map((userGroup) => userGroup.id)), + }); + await userGroupRepo.delete({ + account_id: accountId, + }); + + // テンプレートファイルテーブルのレコードを削除する + const templateFileRepo = entityManager.getRepository(TemplateFile); + await templateFileRepo.delete({ account_id: accountId }); + + // ユーザテーブルのレコードを削除する + const userRepo = entityManager.getRepository(User); + await userRepo.delete({ + account_id: accountId, + }); + + // ソート条件のテーブルのレコードを削除する + const sortCriteriaRepo = entityManager.getRepository(SortCriteria); + await sortCriteriaRepo.delete({ + user_id: In(users.map((user) => user.id)), + }); return users; }); } diff --git a/dictation_server/src/repositories/licenses/entity/license.entity.ts b/dictation_server/src/repositories/licenses/entity/license.entity.ts index dc39e6e..b30018e 100644 --- a/dictation_server/src/repositories/licenses/entity/license.entity.ts +++ b/dictation_server/src/repositories/licenses/entity/license.entity.ts @@ -94,7 +94,9 @@ export class License { @UpdateDateColumn() updated_at: Date; - @OneToOne(() => User, (user) => user.license) + @OneToOne(() => User, (user) => user.license, { + createForeignKeyConstraints: false, + }) // createForeignKeyConstraintsはSQLite用設定値.本番用は別途migrationで設定 @JoinColumn({ name: 'allocated_user_id' }) user?: User; } @@ -185,7 +187,9 @@ export class LicenseAllocationHistory { @UpdateDateColumn() updated_at: Date; - @ManyToOne(() => License, (licenses) => licenses.id) + @ManyToOne(() => License, (licenses) => licenses.id, { + createForeignKeyConstraints: false, + }) // createForeignKeyConstraintsはSQLite用設定値.本番用は別途migrationで設定 @JoinColumn({ name: 'license_id' }) license?: License; } diff --git a/dictation_server/src/repositories/users/entity/user.entity.ts b/dictation_server/src/repositories/users/entity/user.entity.ts index e7399aa..387a668 100644 --- a/dictation_server/src/repositories/users/entity/user.entity.ts +++ b/dictation_server/src/repositories/users/entity/user.entity.ts @@ -73,7 +73,9 @@ export class User { @UpdateDateColumn({ default: () => "datetime('now', 'localtime')" }) // defaultはSQLite用設定値.本番用は別途migrationで設定 updated_at: Date; - @ManyToOne(() => Account, (account) => account.user, { onDelete: 'CASCADE' }) // onDeleteはSQLite用設定値.本番用は別途migrationで設定 + @ManyToOne(() => Account, (account) => account.user, { + createForeignKeyConstraints: false, + }) // createForeignKeyConstraintsはSQLite用設定値.本番用は別途migrationで設定 @JoinColumn({ name: 'account_id' }) account?: Account;