fix: [db] codebridge DB 분리 후 깨진 FK 제약조건 52개 제거

- sam → codebridge 테이블 이동 후 users, tenants 등 참조하는 FK 잔존
- esign_field_templates INSERT 시 FK violation 발생 수정
This commit is contained in:
김보곤
2026-03-11 10:06:24 +09:00
parent 047524c19f
commit 8222ba667f

View File

@@ -0,0 +1,109 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
/**
* codebridge DB 분리 후 남은 깨진 FK 제약조건 제거
*
* 원인: 2026_03_09_230000_drop_codebridge_tables_from_sam 마이그레이션으로
* sam → codebridge로 테이블을 이동했으나, codebridge 테이블의 FK 제약조건이
* 여전히 sam에 남아있는 users, tenants, departments 등을 참조하고 있었음.
*
* 영향: esign_field_templates 등에서 INSERT 시 FK violation 발생
*/
return new class extends Migration
{
public function up(): void
{
$connection = 'codebridge';
// 참조 대상: users (27개)
$this->dropForeignKeySafe($connection, 'admin_api_bookmarks', 'admin_api_bookmarks_user_id_foreign');
$this->dropForeignKeySafe($connection, 'admin_api_deprecations', 'admin_api_deprecations_created_by_foreign');
$this->dropForeignKeySafe($connection, 'admin_api_environments', 'admin_api_environments_user_id_foreign');
$this->dropForeignKeySafe($connection, 'admin_api_histories', 'admin_api_histories_user_id_foreign');
$this->dropForeignKeySafe($connection, 'admin_api_templates', 'admin_api_templates_user_id_foreign');
$this->dropForeignKeySafe($connection, 'admin_meeting_logs', 'admin_meeting_logs_user_id_foreign');
$this->dropForeignKeySafe($connection, 'admin_pm_daily_logs', 'admin_pm_daily_logs_deleted_by_foreign');
$this->dropForeignKeySafe($connection, 'admin_pm_daily_logs', 'admin_pm_daily_logs_created_by_foreign');
$this->dropForeignKeySafe($connection, 'admin_pm_daily_logs', 'admin_pm_daily_logs_updated_by_foreign');
$this->dropForeignKeySafe($connection, 'admin_pm_issues', 'admin_pm_issues_assignee_id_foreign');
$this->dropForeignKeySafe($connection, 'ai_token_usages', 'ai_token_usages_created_by_foreign');
$this->dropForeignKeySafe($connection, 'business_income_payments', 'business_income_payments_confirmed_by_foreign');
$this->dropForeignKeySafe($connection, 'business_income_payments', 'business_income_payments_user_id_foreign');
$this->dropForeignKeySafe($connection, 'business_income_payments', 'business_income_payments_updated_by_foreign');
$this->dropForeignKeySafe($connection, 'business_income_payments', 'business_income_payments_created_by_foreign');
$this->dropForeignKeySafe($connection, 'business_income_payments', 'business_income_payments_deleted_by_foreign');
$this->dropForeignKeySafe($connection, 'demo_links', 'demo_links_created_by_foreign');
$this->dropForeignKeySafe($connection, 'esign_contracts', 'esign_contracts_updated_by_foreign');
$this->dropForeignKeySafe($connection, 'esign_contracts', 'esign_contracts_deleted_by_foreign');
$this->dropForeignKeySafe($connection, 'esign_contracts', 'esign_contracts_created_by_foreign');
$this->dropForeignKeySafe($connection, 'esign_field_templates', 'esign_field_templates_created_by_foreign');
$this->dropForeignKeySafe($connection, 'login_tokens', 'login_tokens_user_id_foreign');
$this->dropForeignKeySafe($connection, 'sales_contract_products', 'sales_contract_products_created_by_foreign');
$this->dropForeignKeySafe($connection, 'sales_manager_documents', 'sales_manager_documents_uploaded_by_foreign');
$this->dropForeignKeySafe($connection, 'sales_manager_documents', 'sales_manager_documents_user_id_foreign');
$this->dropForeignKeySafe($connection, 'sales_scenario_checklists', 'sales_scenario_checklists_user_id_foreign');
$this->dropForeignKeySafe($connection, 'tenant_prospects', 'tenant_prospects_converted_by_foreign');
$this->dropForeignKeySafe($connection, 'tenant_prospects', 'tenant_prospects_registered_by_foreign');
// 참조 대상: tenants (16개)
$this->dropForeignKeySafe($connection, 'account_codes', 'account_codes_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'admin_meeting_logs', 'admin_meeting_logs_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'admin_pm_daily_logs', 'admin_pm_daily_logs_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'ai_token_usages', 'ai_token_usages_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'barobill_bank_sync_status', 'barobill_bank_sync_status_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'barobill_bank_transaction_splits', 'barobill_bank_transaction_splits_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'barobill_bank_transactions', 'barobill_bank_transactions_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'barobill_card_transaction_hides', 'barobill_card_transaction_hides_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'barobill_members', 'barobill_members_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'business_income_payments', 'business_income_payments_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'esign_audit_logs', 'esign_audit_logs_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'esign_contracts', 'esign_contracts_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'esign_field_templates', 'esign_field_templates_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'esign_sign_fields', 'esign_sign_fields_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'esign_signers', 'esign_signers_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'expense_accounts', 'expense_accounts_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'hometax_invoices', 'hometax_invoices_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'sales_contract_products', 'sales_contract_products_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'sales_manager_documents', 'sales_manager_documents_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'sales_scenario_checklists', 'sales_scenario_checklists_tenant_id_foreign');
$this->dropForeignKeySafe($connection, 'tenant_prospects', 'tenant_prospects_tenant_id_foreign');
// 참조 대상: departments (1개)
$this->dropForeignKeySafe($connection, 'admin_pm_issues', 'admin_pm_issues_department_id_foreign');
// 참조 대상: processes (1개)
$this->dropForeignKeySafe($connection, 'equipment_process', 'equipment_process_process_id_foreign');
// 참조 대상: prospects (1개)
$this->dropForeignKeySafe($connection, 'demo_links', 'demo_links_prospect_id_foreign');
// 참조 대상: clients (1개)
$this->dropForeignKeySafe($connection, 'expense_accounts', 'expense_accounts_vendor_id_foreign');
// 참조 대상: barobill_card_transactions (1개)
$this->dropForeignKeySafe($connection, 'barobill_card_transaction_amount_logs', 'bb_amount_log_trans_fk');
}
public function down(): void
{
// 복원 불필요: 크로스 DB FK는 의도적으로 제거한 것
}
private function dropForeignKeySafe(string $connection, string $table, string $foreignKey): void
{
$exists = DB::connection($connection)->select("
SELECT 1 FROM information_schema.TABLE_CONSTRAINTS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = ?
AND CONSTRAINT_NAME = ?
AND CONSTRAINT_TYPE = 'FOREIGN KEY'
", [$table, $foreignKey]);
if (! empty($exists)) {
DB::connection($connection)->statement("ALTER TABLE `{$table}` DROP FOREIGN KEY `{$foreignKey}`");
}
}
};